Update to use kfp-server-api version 2 28/13628/13
authorSungjin Lee <sodyn99@gmail.com>
Wed, 16 Oct 2024 02:13:25 +0000 (02:13 +0000)
committerSungjin Lee <sodyn99@gmail.com>
Thu, 17 Oct 2024 13:28:46 +0000 (13:28 +0000)
- Fix cannot fetch experiments, runs information
- Update test code for kfp-server-api v2.0.5
- Change the '/runs' endpoint to retrieve pipeline information using 'pipeline_id'

ISSUE-ID: AIMLFW-166

Change-Id: I7949bef79a891764319f621189270cc59de03417
Signed-off-by: Sungjin Lee <sodyn99@gmail.com>
kfadapter/kfadapter_main.py
test/fake_kfp.py
test/test_kfadapter_main.py
tox.ini

index 8670679..f129690 100644 (file)
@@ -86,8 +86,8 @@ def get_experiment(expname):
         LOGGER.debug("Experiment name is present")
 
         LOGGER.debug(exp)
-        exp_dict['name'] = exp.name
-        exp_dict['id'] = exp.id
+        exp_dict['name'] = exp.display_name
+        exp_dict['id'] = exp.experiment_id
     except ValueError as err:
         LOGGER.error(err)
         raise BadRequest('Experiment name does not exist', status.HTTP_400_BAD_REQUEST,\
@@ -308,7 +308,7 @@ def list_pipelines():
         pipeline_list = KFCONNECT_KF_OBJ.get_kf_list_pipelines()
         pipe_dict['next_page_token'] = pipeline_list.next_page_token
         pipe_dict['total_size'] = pipeline_list.total_size
-        
+
         pipelines = []
         for pipeline in pipeline_list.pipelines:
             pipe_super_dict = {}
@@ -318,7 +318,7 @@ def list_pipelines():
             pipe_super_dict['created_at'] = pipeline.created_at
             pipelines.append(pipe_super_dict)
         pipe_dict['pipelines'] = pipelines
-        
+
     except:# pylint: disable=bare-except
         tbk = traceback.format_exc()
         LOGGER.error(tbk)
@@ -439,18 +439,22 @@ def list_runs():
         runs = KFCONNECT_KF_OBJ.get_kf_list_runs(KFCONNECT_CONFIG_OBJ.kf_dict['kfdefaultns'])
 
         for run in runs.runs:
+            LOGGER.debug(f"Run: {run}")
             run_super_dict = {}
-            run_super_dict['run_id'] = run.id
+            run_super_dict['run_id'] = run.run_id
             run_super_dict['run_description'] = run.description
-            run_super_dict['run_status'] = run.status
-            run_super_dict['experiment_name'] = run.resource_references[0].name
-            run_super_dict['experiment_id'] = run.resource_references[0].key.id
+            run_super_dict['run_status'] = run.state
+            run_super_dict['experiment_id'] = run.experiment_id
+
+            LOGGER.debug(f"Pipeline version reference: {run.pipeline_version_reference}")
+            LOGGER.debug(f"Pipeline version reference ID: {run.pipeline_version_reference.pipeline_id}")
 
-            if len(run.resource_references) > 1:
-                run_super_dict['pipeline_name'] = run.resource_references[1].name
-                run_super_dict['pipeline_id'] = run.resource_references[1].key.id
+            if run.pipeline_version_reference is not None:
+                pipeline_info = KFCONNECT_KF_OBJ.get_kf_pipeline_desc(run.pipeline_version_reference.pipeline_id)
+                run_super_dict['pipeline_name'] = pipeline_info.display_name
+                run_super_dict['pipeline_id'] = pipeline_info.pipeline_id
 
-            run_dict[run.name] = run_super_dict
+            run_dict[run.display_name] = run_super_dict
     except:# pylint: disable=bare-except
         tbk = traceback.format_exc()
         LOGGER.error(tbk)
index c80cd1a..0bd6ac2 100644 (file)
 
 from typing import Optional
 
-from kfp_server_api.models.api_list_pipeline_versions_response import ApiListPipelineVersionsResponse
-from kfp_server_api.models.api_pipeline_version import ApiPipelineVersion
-from kfp_server_api.models.api_experiment import ApiExperiment
-from kfp_server_api.models.api_run_detail import ApiRunDetail
-from kfp_server_api.models.api_run import ApiRun
+from kfp_server_api.models.v2beta1_list_pipeline_versions_response import V2beta1ListPipelineVersionsResponse as ApiListPipelineVersionsResponse
+from kfp_server_api.models.v2beta1_pipeline_version import V2beta1PipelineVersion as ApiPipelineVersion
+from kfp_server_api.models.v2beta1_experiment import V2beta1Experiment as ApiExperiment
+from kfp_server_api.models.v2beta1_run_details import V2beta1RunDetails as ApiRunDetail
+from kfp_server_api.models.v2beta1_run import V2beta1Run as ApiRun
 import kfp_server_api
 
 class FakeKfp:
@@ -41,9 +41,9 @@ class FakeKfp:
         exp = ApiExperiment()
         exp.id = 'ex-id'
         exp.name = 'exp-name'
-        return exp 
+        return exp
+
 
-    
     def upload_pipeline_version(
         self,
         pipeline_package_path,
@@ -70,27 +70,27 @@ class FakeKfp:
                   experiment_id=None,
                   namespace=None,
                   filter=None):
-        
+
         listrun = ApiListRunsResponse()
         run1 = ApiRun()
         run1.id(self, 'id')
-        run1.description(self, 'description') 
-        run1.status(self, 'status')  
+        run1.description(self, 'description')
+        run1.status(self, 'status')
         rr0 = ApiResourceReference()
         rr0.name(self, 'name')
         key0 = ApiResourceKey()
         key0.id(self, 'id')
         rr0.key(self, key0)
-  
+
         rr1 = ApiResourceReference()
         rr1.name(self, 'name')
         key1 = ApiResourceKey()
         key1.id(self, 'id')
         rr1.key(key1)
-    
+
         run1.resource_references(self, rr0)
-        listrun.runs(self, [run1]) 
-    
+        listrun.runs(self, [run1])
+
         return listrun
     """
 
@@ -132,7 +132,7 @@ class FakeKfp:
         service_account: Optional[str] = None,
     ):
         return None
-    
+
 
     def delete_pipeline(self, pipeline_id):
         return None
@@ -145,7 +145,7 @@ class FakeKfp:
                        page_size=10,
                        sort_by=''):
         return None
-    
+
 
     def upload_pipeline(
         self,
@@ -156,7 +156,7 @@ class FakeKfp:
         return None
 
     def get_pipeline_id(self, name):
-        
+
         return ['pipelin_id', 'pipelin_id2',]
 
 
@@ -206,8 +206,8 @@ class FakeNegativeKfp:
                        experiment_name=None,
                        namespace=None):
         raise ValueError(
-                'Either experiment_id or experiment_name is required') 
-    
+                'Either experiment_id or experiment_name is required')
+
 class FakeAdditionalKfp:
     """
     def list_pipeline_versions(
@@ -231,7 +231,7 @@ class FakeAdditionalKfp:
     """
     def get_pipeline_id(self, name):
         return None
-        
+
     def upload_pipeline(
         self,
         pipeline_package_path: str = None,
index eae6232..05787d0 100644 (file)
 import json
 import io
 from unittest import TestCase
-from mock import patch
+from mock import patch, MagicMock
 from flask_api import status
 
 import kfp_server_api
-from kfp_server_api.models.api_run import ApiRun
-from kfp_server_api.models.api_list_runs_response import ApiListRunsResponse
-from kfp_server_api.models.api_experiment import ApiExperiment
-from kfp_server_api.models.api_list_pipelines_response import ApiListPipelinesResponse
-from kfp_server_api.models.api_pipeline import ApiPipeline
-from kfp_server_api.models.api_parameter import ApiParameter
-from kfp_server_api.models.api_resource_reference import ApiResourceReference
-from kfp_server_api.models.api_resource_key import ApiResourceKey
-from kfp_server_api.models.api_pipeline_version import ApiPipelineVersion
+from kfp_server_api.models.v2beta1_run import V2beta1Run as ApiRun
+from kfp_server_api.models.v2beta1_list_runs_response import V2beta1ListRunsResponse as ApiListRunsResponse
+from kfp_server_api.models.v2beta1_experiment import V2beta1Experiment as ApiExperiment
+from kfp_server_api.models.v2beta1_list_pipelines_response import V2beta1ListPipelinesResponse as ApiListPipelinesResponse
+from kfp_server_api.models.v2beta1_pipeline import V2beta1Pipeline as ApiPipeline
+from kfp_server_api.models.v2beta1_runtime_config import V2beta1RuntimeConfig as ApiParameter
+from kfp_server_api.models.v2beta1_pipeline_version import V2beta1PipelineVersion as ApiPipelineVersion
 from kfadapter import kfadapter_main
 from kfadapter import kfadapter_conf
 from kfadapter import kfadapter_kfconnect
@@ -46,53 +44,72 @@ class testKfadapterApi(TestCase):
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details")
-    def test_get_experiment(self, mock_get_kf_experiment_details): 
+    def test_get_experiment(self, mock_get_kf_experiment_details):
         # given
         exp = ApiExperiment()
-        exp.name = "exp-name"
-        exp.id = "exp-id"
+        exp.display_name = "exp-name"
+        exp.experiment_id = "exp-id"
         mock_get_kf_experiment_details.return_value = exp
 
         # when
-        response = self.client.get("/experiments/{}".format(exp.name))
-        
+        response = self.client.get("/experiments/{}".format(exp.display_name))
+
         # then
         mock_get_kf_experiment_details.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(response.get_json()["name"], exp.name)
-        self.assertEqual(response.get_json()["id"], exp.id)
-    
+        self.assertEqual(response.get_json()["name"], exp.display_name)
+        self.assertEqual(response.get_json()["id"], exp.experiment_id)
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_runs")
-    def test_get_all_runs(self, mock_get_kf_list_runs):
+    @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_desc")
+    def test_get_all_runs(self, mock_get_kf_pipeline_desc, mock_get_kf_list_runs):
+        class PipelineVersionReference:
+            def __init__(self, pipeline_id, pipeline_version_id):
+                self.pipeline_id = pipeline_id
+                self.pipeline_version_id = pipeline_version_id
+
         # given
-        resources = [ ApiResourceReference() for _ in range(3)]
-        for i, resource in enumerate(resources) :
-            resource.name = "rr-name{}".format(i)
-            resource.key = ApiResourceKey()
-            resource.key.id = "rr-id{}".format(i)
-  
-        runs = [ ApiRun() for _ in range(2)]
-        for i, run in enumerate(runs) :
-            run.id = "runid" 
-            run.description = "description" 
-            run.status = "status"  
-            run.resource_references = [resources[i], resources[i+1]]
-                    
+        runs = [ApiRun() for _ in range(2)]
+        for i, run in enumerate(runs):
+            run.run_id = "runid"
+            run.display_name = f"run-name{i}"
+            run.description = "description"
+            run.state = "status"
+            run.pipeline_version_reference = PipelineVersionReference(
+                pipeline_id=f"pipeline-id{i}",
+                pipeline_version_id=f"pipeline-version-id{i}"
+            )
+            run.experiment_id = f"experiment-id{i}"
+
         list_run = ApiListRunsResponse()
         list_run.runs = runs
         mock_get_kf_list_runs.return_value = list_run
 
+        # Mocking get_kf_pipeline_desc to return a mock pipeline info
+        def mock_pipeline_desc(pipeline_id):
+            pipeline = MagicMock()
+            pipeline.display_name = f"pipeline-name{pipeline_id[-1]}"
+            pipeline.pipeline_id = pipeline_id
+            return pipeline
+
+        mock_get_kf_pipeline_desc.side_effect = mock_pipeline_desc
+
         # when
         response = self.client.get("/runs")
+        print('response:', response.get_data())
 
         # then
         mock_get_kf_list_runs.assert_called_once()
+        mock_get_kf_pipeline_desc.assert_any_call("pipeline-id0")
+        mock_get_kf_pipeline_desc.assert_any_call("pipeline-id1")
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(response.get_data(), b'{"null":{"experiment_id":"rr-id1","experiment_name":"rr-name1","pipeline_id":"rr-id2","pipeline_name":"rr-name2","run_description":"description","run_id":"runid","run_status":"status"}}\n')
-
+        self.assertEqual(
+            response.get_data(),
+            b'{"run-name0":{"experiment_id":"experiment-id0","pipeline_id":"pipeline-id0","pipeline_name":"pipeline-name0","run_description":"description","run_id":"runid","run_status":"status"},"run-name1":{"experiment_id":"experiment-id1","pipeline_id":"pipeline-id1","pipeline_name":"pipeline-name1","run_description":"description","run_id":"runid","run_status":"status"}}\n'
+        )
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_id")
     def test_get_pipeline_id(self, mock_get_kf_pipeline_id):
@@ -103,8 +120,8 @@ class testKfadapterApi(TestCase):
 
         # when
         response = self.client.get("/pipelineIds/{}".format(pipeline_name))
-        
-        # then        
+
+        # then
         mock_get_kf_pipeline_id.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -121,7 +138,7 @@ class testKfadapterApi(TestCase):
         pipeline_info = ApiPipeline()
         pipeline_info.pipeline_id = pipeline_id
         mock_upload_pipeline_with_versions.return_value = pipeline_info
-        
+
         files = {}
         files['file'] = (io.BytesIO(b"pipeline-file"), 'pipeline')
         files['description'] = "pipeline-description"
@@ -135,7 +152,7 @@ class testKfadapterApi(TestCase):
         self.assertEqual(response.status_code, status.HTTP_200_OK)
         self.assertEqual(response.get_json()['name'], pipeline_name)
         self.assertEqual(response.get_json()['id'], pipeline_id)
-        
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_pl_versions_by_pl_name")
     def test_get_pipeline_version(self, mock_get_pl_versions_by_pl_name):
@@ -162,7 +179,7 @@ class testKfadapterApi(TestCase):
         run.display_name = "run-name"
         run.state = "Running"
         mock_get_kf_run.return_value = run
-        
+
         # when
         response = self.client.get("/runs/{}".format(run.run_id))
 
@@ -185,12 +202,12 @@ class testKfadapterApi(TestCase):
         # then
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
-    
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_pipelines")
     def test_get_pipelines(self, mock_get_kf_list_pipelines):
 
-       #given 
+       #given
         pipeline = ApiPipeline()
         pipeline.pipeline_id = "pipeline-id"
         pipeline.description = "pipeline-description"
@@ -204,7 +221,7 @@ class testKfadapterApi(TestCase):
         pipeline_list.total_size = "total-size"
 
         mock_get_kf_list_pipelines.return_value = pipeline_list
-        
+
         # when
         response = self.client.get("/pipelines")
 
@@ -212,7 +229,7 @@ class testKfadapterApi(TestCase):
         mock_get_kf_list_pipelines.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(response.get_data(), 
+        self.assertEqual(response.get_data(),
                          b'{"next_page_token":"next-page-token","pipelines":[{"created_at":"created-at","description":"pipeline-description","display_name":"pipeline-name","pipeline_id":"pipeline-id"}],"total_size":"total-size"}\n')
 
 
@@ -233,11 +250,11 @@ class testKfadapterApi(TestCase):
         pipeline_info.description = "description"
         pipeline_info.id = pipeline_name
         pipeline_info.name = pipeline_id
-        
+
         default_version = ApiPipelineVersion()
-        default_version.parameters = [params[2], params[3]]    
+        default_version.parameters = [params[2], params[3]]
         pipeline_info.default_version = default_version
-        mock_get_kf_pipeline_desc.return_value = pipeline_info  
+        mock_get_kf_pipeline_desc.return_value = pipeline_info
 
         # when
         response = self.client.get("/pipelines/{}".format(pipeline_id))
@@ -264,7 +281,7 @@ class testKfadapterApi(TestCase):
         self.assertEqual(response.status_code, status.HTTP_200_OK)
         self.assertEqual(response.get_json()["id"], pipeline_id)
         self.assertEqual(response.get_json()["status"], "Deleted")
-        
+
 
     def test_check_liveness(self):
         # when
@@ -279,11 +296,11 @@ class testKfadapterApi(TestCase):
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_experiments")
     def test_get_experiments(self, mock_get_kf_list_experiments):
         # given
-        exp = kfp_server_api.ApiExperiment()
+        exp = ApiExperiment()
         exp.display_name = "exp-name"
         exp.experiment_id = "exp-id"
 
-        explist = kfp_server_api.ApiListExperimentsResponse()
+        explist = kfp_server_api.V2beta1ListExperimentsResponse()
         explist.experiments = [exp]
         mock_get_kf_list_experiments.return_value = explist
 
@@ -311,7 +328,7 @@ class testKfadapterApi(TestCase):
         pipeline_name = "pipeline-name"
         pipeline_id = "pipeline-id"
         mock_get_kf_pipeline_id.return_value = pipeline_id
-                
+
         params = [ ApiParameter() for _ in range(4)]
         for i, param in enumerate(params) :
             param.name = "param-name{}".format(i)
@@ -322,20 +339,20 @@ class testKfadapterApi(TestCase):
         pipeline_info.description = "pipeline-description"
         pipeline_info.id = pipeline_name
         pipeline_info.name = pipeline_id
-        
+
         mock_get_kf_pipeline_version_id.return_value = pipeline_id
 
         run = {}
         run["display_name"] = "run-name"
         run["run_id"] = "run-id"
-        pipeline_id= "pipeline_id" 
+        pipeline_id= "pipeline_id"
         pipeline_version_reference= {'pipeline_id': pipeline_id,
                                 'pipeline_version_id': pipeline_id}
         run["pipeline_version_reference"]=pipeline_version_reference
-          
+
         run["state"] = "RUNNING"
         mock_run_kf_pipeline.return_value = run
-        
+
 
         job_name = "job_name"
         dict_job = {}
@@ -383,7 +400,7 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_pl_versions_by_pl_name.assert_called_once()
         self.assertEqual(response.content_type, "text/html; charset=utf-8")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_pl_versions_by_pl_name")
     def test_negative_get_versions_for_pipeline_failed_with_unsupported_error(self, mock_get_pl_versions_by_pl_name):
@@ -398,8 +415,8 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_pl_versions_by_pl_name.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-        self.assertEqual(response.get_json()["ext"], 1) 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+        self.assertEqual(response.get_json()["ext"], 1)
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_desc")
@@ -420,7 +437,7 @@ class testNegativeKfadapterApi(TestCase):
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_id")
-    def test_negative_get_pipeline_id_failed_with_value_error(self, mock_get_kf_pipeline_id): 
+    def test_negative_get_pipeline_id_failed_with_value_error(self, mock_get_kf_pipeline_id):
         # given
         pipeline_name = "pipeline-name"
         mock_get_kf_pipeline_id.return_value = None
@@ -428,20 +445,20 @@ class testNegativeKfadapterApi(TestCase):
         # when
         response = self.client.get("/pipelineIds/{}".format(pipeline_name))
 
-        # then        
+        # then
         mock_get_kf_pipeline_id.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertEqual(response.get_json()["message"],"PipeLine Name does not exist")
         self.assertEqual(response.get_json()["payload"],{"error":"No pipeline is found with name pipeline-name","pipe_name":pipeline_name})
-    
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.upload_pipeline_with_versions")
     def test_negative_upload_pipeline_failed_with_api_exception(self, mock_upload_pipeline_with_versions):
         # given
         pipeline_name = "pipeline-name"
 
-        mock_upload_pipeline_with_versions.side_effect = kfp_server_api.exceptions.ApiException        
+        mock_upload_pipeline_with_versions.side_effect = kfp_server_api.exceptions.ApiException
 
         files = {}
         files['file'] = (io.BytesIO(b"pipeline-file"), 'pipeline.zip')
@@ -452,12 +469,12 @@ class testNegativeKfadapterApi(TestCase):
 
         # then
         mock_upload_pipeline_with_versions.assert_called_once()
-        self.assertEqual(response.content_type, "text/html; charset=utf-8")        
+        self.assertEqual(response.content_type, "text/html; charset=utf-8")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
 
 
     def test_negative_upload_pipeline_failed_cause_empty_file_name(self):
-        # given       
+        # given
         pipeline_name = "pipeline-name"
 
         files = {}
@@ -470,8 +487,8 @@ class testNegativeKfadapterApi(TestCase):
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
         self.assertEqual(response.get_json()["message"],"Unsupported error from Kubeflow")
-        self.assertEqual(response.get_json()["ext"], 1) 
-    
+        self.assertEqual(response.get_json()["ext"], 1)
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details")
     def test_negative_get_experiment_failed_cause_no_such_experiment(self, mock_get_kf_experiment_details):
@@ -503,8 +520,8 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_experiment_details.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-        self.assertEqual(response.get_json()["ext"], 1) 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+        self.assertEqual(response.get_json()["ext"], 1)
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_run")
@@ -512,7 +529,7 @@ class testNegativeKfadapterApi(TestCase):
         # given
         run_id = "run-id"
         mock_get_kf_run.side_effect = Exception("")
-        
+
         # when
         response = self.client.get("/runs/{}".format(run_id))
 
@@ -536,15 +553,15 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_list_runs.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-        self.assertEqual(response.get_json()["ext"], 1) 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+        self.assertEqual(response.get_json()["ext"], 1)
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_pipelines")
     def test_negative_get_pipelines_failed_with_unsupported_error(self, mock_get_kf_list_pipelines):
         # given
         mock_get_kf_list_pipelines.side_effect = IndexError("")
-        
+
         # when
         response = self.client.get("/pipelines")
 
@@ -552,8 +569,8 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_list_pipelines.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-        self.assertEqual(response.get_json()["ext"], 1) 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+        self.assertEqual(response.get_json()["ext"], 1)
 
 
     def test_negative_execute_job_failed_cause_less_arguments(self):
@@ -567,9 +584,9 @@ class testNegativeKfadapterApi(TestCase):
         # then
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
-        self.assertEqual(response.get_json()["message"], "Less arguments") 
-        self.assertFalse(response.get_json()["payload"]) 
-       
+        self.assertEqual(response.get_json()["message"], "Less arguments")
+        self.assertFalse(response.get_json()["payload"])
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details")
     def test_negative_execute_job_failed_cause_no_such_experiment(self, mock_get_kf_experiment_details):
@@ -582,13 +599,13 @@ class testNegativeKfadapterApi(TestCase):
         for i, param in enumerate(params) :
             param.name = "param-name{}".format(i)
             param.value = "param-value{}".format(i)
-        
+
         args = {}
         args[params[0].name] = params[0].value
         args[params[1].name] = params[1].value
-        
+
         dict_job["arguments"] = args
-        dict_job["pipeline_name"] = "pipeline-name"        
+        dict_job["pipeline_name"] = "pipeline-name"
         dict_job["pipeline_version"] = "2.0.0"
         dict_job["experiment_name"] = "exp-name"
 
@@ -599,7 +616,7 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_experiment_details.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
 
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details")
@@ -611,7 +628,7 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_experiment_details.return_value = exp
 
         mock_get_kf_pipeline_id.return_value = None
-                
+
         job_name = "job_name"
         dict_job = {}
 
@@ -619,13 +636,13 @@ class testNegativeKfadapterApi(TestCase):
         for i, param in enumerate(params) :
             param.name = "param-name{}".format(i)
             param.value = "param-value{}".format(i)
-        
+
         args = {}
         args[params[0].name] = params[0].value
         args[params[1].name] = params[1].value
-        
+
         dict_job["arguments"] = args
-        dict_job["pipeline_name"] = "pipeline-name"        
+        dict_job["pipeline_name"] = "pipeline-name"
         dict_job["pipeline_version"] = "2.0.0"
         dict_job["experiment_name"] = exp_name
 
@@ -637,8 +654,8 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_pipeline_id.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-    
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+
 
     @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_experiments")
     def test_negative_get_experiments_failed_with_unsupported_error(self, mock_get_kf_list_experiments):
@@ -652,5 +669,5 @@ class testNegativeKfadapterApi(TestCase):
         mock_get_kf_list_experiments.assert_called_once()
         self.assertEqual(response.content_type, "application/json")
         self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
-        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") 
-        self.assertEqual(response.get_json()["ext"], 1) 
+        self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow")
+        self.assertEqual(response.get_json()["ext"], 1)
diff --git a/tox.ini b/tox.ini
index fb8796f..8f793e9 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -30,15 +30,15 @@ deps=
   mock
   kfp
   kfp-pipeline-spec
-  kfp-server-api==1.8.5
+  kfp-server-api
   Flask
   Flask-API
   Flask-Cors
   requests
   Werkzeug==2.2.2
-  
+
 setenv = cd = {toxinidir}/test
-commands = 
+commands =
   pip3 install {toxinidir}
 
   pytest --cov {toxinidir}/kfadapter --cov-report xml --cov-report term-missing --cov-report html --cov-fail-under=10 --junitxml=/tmp/tests.xml