From 6399905a0f4073e222d5b3c4a9c6707be649681f Mon Sep 17 00:00:00 2001 From: Honglin Date: Thu, 25 Apr 2024 18:39:23 +0800 Subject: [PATCH] [SDK/CLI] Write instance_results.jsonl path in run properties (#3014) # Description Please add an informative description that covers that changes made by the pull request and link all relevant issues. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- .../e2etests/test_run_upload.py | 27 +++++-------------- .../promptflow/_sdk/_constants.py | 2 +- .../promptflow/_sdk/entities/_run.py | 6 ++++- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py index 699517ea992..74600c144a9 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py @@ -51,6 +51,7 @@ def check_local_to_cloud_run(pf: PFClient, run: Run, check_run_details_in_cloud: assert cloud_run.properties["azureml.promptflow.local_to_cloud"] == "true" assert cloud_run.properties["azureml.promptflow.snapshot_id"] assert cloud_run.properties[Local2CloudProperties.TOTAL_TOKENS] + assert cloud_run.properties[Local2CloudProperties.EVAL_ARTIFACTS] # if no description or tags, skip the check, since one could be {} but the other is None if run.description: @@ -74,12 +75,12 @@ def check_local_to_cloud_run(pf: PFClient, run: Run, check_run_details_in_cloud: "mock_set_headers_with_user_aml_token", "single_worker_thread_pool", "vcr_recording", + "mock_isinstance_for_mock_datastore", + "mock_get_azure_pf_client", + "mock_trace_destination_to_cloud", ) class TestFlowRunUpload: @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_run( self, pf: PFClient, @@ -103,9 +104,6 @@ def test_upload_run( Local2CloudTestHelper.check_local_to_cloud_run(pf, run, check_run_details_in_cloud=True) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_flex_flow_run_with_yaml(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("flex_run_name_with_yaml_for_upload") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -125,9 +123,6 @@ def test_upload_flex_flow_run_with_yaml(self, pf: PFClient, randstr: Callable[[s Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_flex_flow_run_without_yaml(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("flex_run_name_without_yaml_for_upload") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -148,9 +143,6 @@ def test_upload_flex_flow_run_without_yaml(self, pf: PFClient, randstr: Callable Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_prompty_run(self, pf: PFClient, randstr: Callable[[str], str]): # currently prompty run is skipped for upload, this test should be finished without error name = randstr("prompty_run_name_for_upload") @@ -167,9 +159,6 @@ def test_upload_prompty_run(self, pf: PFClient, randstr: Callable[[str], str]): Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_run_with_customized_run_properties(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("batch_run_name_for_upload_with_customized_properties") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -200,9 +189,6 @@ def test_upload_run_with_customized_run_properties(self, pf: PFClient, randstr: assert cloud_run.properties[Local2CloudUserProperties.EVAL_ARTIFACTS] == eval_artifacts @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): main_run_name = randstr("main_run_name_for_test_upload_eval_run") local_pf = Local2CloudTestHelper.get_local_pf(main_run_name) @@ -216,8 +202,8 @@ def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): # run an evaluation run eval_run_name = randstr("eval_run_name_for_test_upload_eval_run") - local_lpf = Local2CloudTestHelper.get_local_pf(eval_run_name) - eval_run = local_lpf.run( + local_pf = Local2CloudTestHelper.get_local_pf(eval_run_name) + eval_run = local_pf.run( flow=f"{FLOWS_DIR}/simple_hello_world", data=f"{DATAS_DIR}/webClassification3.jsonl", run=main_run_name, @@ -229,7 +215,6 @@ def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): assert eval_run.properties["azureml.promptflow.variant_run_id"] == main_run_name @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures("mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client") def test_upload_flex_flow_run_with_global_azureml(self, pf: PFClient, randstr: Callable[[str], str]): with patch("promptflow._sdk._configuration.Configuration.get_config", return_value="azureml"): name = randstr("flex_run_name_with_global_azureml_for_upload") diff --git a/src/promptflow-devkit/promptflow/_sdk/_constants.py b/src/promptflow-devkit/promptflow/_sdk/_constants.py index f4dc2ec4b24..a90ac6df468 100644 --- a/src/promptflow-devkit/promptflow/_sdk/_constants.py +++ b/src/promptflow-devkit/promptflow/_sdk/_constants.py @@ -483,13 +483,13 @@ class Local2CloudProperties: """Run properties that server needs when uploading local run to cloud.""" TOTAL_TOKENS = "azureml.promptflow.total_tokens" + EVAL_ARTIFACTS = "_azureml.evaluate_artifacts" class Local2CloudUserProperties: """Run properties that user can specify when uploading local run to cloud.""" RUN_TYPE = "runType" - EVAL_ARTIFACTS = "_azureml.evaluate_artifacts" @staticmethod def get_all_values(): diff --git a/src/promptflow-devkit/promptflow/_sdk/entities/_run.py b/src/promptflow-devkit/promptflow/_sdk/entities/_run.py index bb91d25d3ca..ef593597fd4 100644 --- a/src/promptflow-devkit/promptflow/_sdk/entities/_run.py +++ b/src/promptflow-devkit/promptflow/_sdk/entities/_run.py @@ -711,7 +711,11 @@ def _to_rest_object_for_local_to_cloud(self, local_to_cloud_info: dict, variant_ # extract properties that needs to be passed to the request total_tokens = self.properties[FlowRunProperties.SYSTEM_METRICS].get("total_tokens", 0) - properties = {Local2CloudProperties.TOTAL_TOKENS: total_tokens} + properties = { + Local2CloudProperties.TOTAL_TOKENS: total_tokens, + # add instance_results.jsonl path to run properties, which is required by UI feature. + Local2CloudProperties.EVAL_ARTIFACTS: '[{"path": "instance_results.jsonl", "type": "table"}]', + } for property_key in Local2CloudUserProperties.get_all_values(): value = self.properties.get(property_key, None) if value is not None: