diff --git a/mlrun/api/crud/pipelines.py b/mlrun/api/crud/pipelines.py index f547c760d51..c7483f16456 100644 --- a/mlrun/api/crud/pipelines.py +++ b/mlrun/api/crud/pipelines.py @@ -89,15 +89,8 @@ def get_pipeline( if api_run_detail.run: run = api_run_detail.to_dict()["run"] if project and project != "*": - # we need to resolve the project from the returned run for the project enforcement here, so we - # can't really get back only the names here - computed_format = ( - mlrun.api.schemas.PipelinesFormat.metadata_only - if format_ == mlrun.api.schemas.PipelinesFormat.name_only - else format_ - ) - run_for_project = self._format_run(db_session, run, computed_format) - if run_for_project["project"] != project: + run_project = self.resolve_project_from_pipeline(run) + if run_project != project: raise mlrun.errors.MLRunInvalidArgumentError( f"Pipeline run with id {run_id} is not of project {project}" ) diff --git a/tests/api/api/test_pipelines.py b/tests/api/api/test_pipelines.py index 835a23dbcbc..d77a749b0d9 100644 --- a/tests/api/api/test_pipelines.py +++ b/tests/api/api/test_pipelines.py @@ -96,6 +96,36 @@ def test_get_pipeline_formats( _assert_get_pipeline_response(expected_run, response) +def test_get_pipeline_specific_project( + db: sqlalchemy.orm.Session, + client: fastapi.testclient.TestClient, + kfp_client_mock: kfp.Client, +) -> None: + for format_ in [ + mlrun.api.schemas.PipelinesFormat.full, + mlrun.api.schemas.PipelinesFormat.metadata_only, + mlrun.api.schemas.PipelinesFormat.summary, + mlrun.api.schemas.PipelinesFormat.name_only, + ]: + project = "project-name" + api_run_detail = _generate_get_run_mock() + _mock_get_run(kfp_client_mock, api_run_detail) + mlrun.api.crud.Pipelines().resolve_project_from_pipeline = unittest.mock.Mock( + return_value=project + ) + response = client.get( + f"/api/projects/{project}/pipelines/{api_run_detail.run.id}", + params={"format": format_}, + ) + expected_run = mlrun.api.crud.Pipelines()._format_run( + db, api_run_detail.to_dict()["run"], format_, api_run_detail.to_dict() + ) + _assert_get_pipeline_response(expected_run, response) + + # revert mock setting (it's global function, without reloading it the mock will persist to following tests) + importlib.reload(mlrun.api.crud) + + def test_list_pipelines_specific_project( db: sqlalchemy.orm.Session, client: fastapi.testclient.TestClient,