From f4af7192059d009b0f3e5f0b5d3dc78edd7a3784 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 21 Oct 2022 18:10:48 +0800 Subject: [PATCH 1/5] support identity in node --- .../azure/ai/ml/entities/_builders/command.py | 5 + .../azure/ai/ml/entities/_credentials.py | 65 +- .../tests/dsl/e2etests/test_dsl_pipeline.py | 81 +- .../dsl/unittests/test_command_builder.py | 49 +- .../tests/dsl/unittests/test_dsl_pipeline.py | 183 +++-- .../unittests/test_pipeline_job_entity.py | 3 + ...pipeline_node_identity_with_component.json | 754 ++++++++++++++++++ 7 files changed, 1082 insertions(+), 58 deletions(-) create mode 100644 sdk/ml/azure-ai-ml/tests/recordings/dsl/e2etests/test_dsl_pipeline.pyTestDSLPipelinetest_pipeline_node_identity_with_component.json diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_builders/command.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_builders/command.py index 18b99b098f17..cecc205ae19f 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_builders/command.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_builders/command.py @@ -474,6 +474,7 @@ def _to_rest_object(self, **kwargs) -> dict: "limits": get_rest_dict_for_node_attrs(self.limits, clear_empty_value=True), "resources": get_rest_dict_for_node_attrs(self.resources, clear_empty_value=True), "services": get_rest_dict_for_node_attrs(self.services), + "identity": self.identity._to_dict() if self.identity else None, }.items(): if value is not None: rest_obj[key] = value @@ -529,6 +530,9 @@ def _from_rest_object(cls, obj: dict) -> "Command": rest_limits = RestCommandJobLimits.from_dict(obj["limits"]) obj["limits"] = CommandJobLimits()._from_rest_object(rest_limits) + if "identity" in obj and obj["identity"]: + obj["identity"] = _BaseJobIdentityConfiguration._load(obj["identity"]) + return Command(**obj) @classmethod @@ -621,6 +625,7 @@ def __call__(self, *args, **kwargs) -> "Command": node.distribution = copy.deepcopy(self.distribution) node.resources = copy.deepcopy(self.resources) node.services = copy.deepcopy(self.services) + node.identity = copy.deepcopy(self.identity) return node msg = "Command can be called as a function only when referenced component is {}, currently got {}." raise ValidationException( diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py index 5e1b64b85151..626c5388a546 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py @@ -5,11 +5,12 @@ # pylint: disable=protected-access,redefined-builtin from abc import ABC -from typing import List +from typing import List, Dict, Union from azure.ai.ml._azure_environments import _get_active_directory_url_from_metadata from azure.ai.ml._utils.utils import camel_to_snake, snake_to_pascal -from azure.ai.ml.entities._mixins import RestTranslatableMixin, DictMixin +from azure.ai.ml.constants._common import CommonYamlFields +from azure.ai.ml.entities._mixins import RestTranslatableMixin, DictMixin, YamlTranslatableMixin from azure.ai.ml._restclient.v2022_05_01.models import ( AccountKeyDatastoreCredentials as RestAccountKeyDatastoreCredentials, AccountKeyDatastoreSecrets as RestAccountKeyDatastoreSecrets, @@ -46,7 +47,7 @@ from azure.ai.ml._restclient.v2022_10_01_preview.models import IdentityConfiguration as RestJobIdentityConfiguration -from azure.ai.ml.exceptions import ErrorTarget, ErrorCategory, JobException +from azure.ai.ml.exceptions import ErrorTarget, ErrorCategory, JobException, ValidationErrorType, ValidationException from azure.ai.ml._restclient.v2022_05_01.models import ( ManagedServiceIdentity as RestManagedServiceIdentityConfiguration, @@ -318,7 +319,7 @@ def __ne__(self, other: object) -> bool: return not self.__eq__(other) -class _BaseJobIdentityConfiguration(ABC, RestTranslatableMixin, DictMixin): +class _BaseJobIdentityConfiguration(ABC, RestTranslatableMixin, DictMixin, YamlTranslatableMixin): def __init__(self): self.type = None @@ -342,6 +343,29 @@ def _from_rest_object(cls, obj: RestJobIdentityConfiguration) -> "Identity": error_category=ErrorCategory.SYSTEM_ERROR, ) + @classmethod + def _load( + cls, + data: Dict = None, + ) -> Union["ManagedIdentityConfiguration", "UserIdentityConfiguration", "AmlTokenConfiguration"]: + type_str = data.get(CommonYamlFields.TYPE) + if type_str == camel_to_snake(ConnectionAuthType.MANAGED_IDENTITY): + identity_cls = ManagedIdentityConfiguration + elif type_str == camel_to_snake(IdentityConfigurationType.USER_IDENTITY): + identity_cls = UserIdentityConfiguration + elif type_str == camel_to_snake(IdentityConfigurationType.AML_TOKEN): + identity_cls = AmlTokenConfiguration + else: + msg = f"Unsupported identity type: {type_str}." + raise ValidationException( + message=msg, + no_personal_data_message=msg, + target=ErrorTarget.IDENTITY, + error_category=ErrorCategory.USER_ERROR, + error_type=ValidationErrorType.INVALID_VALUE, + ) + return identity_cls._load_from_dict(data) + class ManagedIdentityConfiguration(_BaseIdentityConfiguration): """Managed Identity Credentials. @@ -418,6 +442,17 @@ def _from_workspace_rest_object(cls, obj: RestUserAssignedIdentityConfiguration) client_id=obj.client_id, ) + def _to_dict(self) -> Dict: + from azure.ai.ml._schema.job.identity import ManagedIdentitySchema + + return ManagedIdentitySchema().dump(self) + + @classmethod + def _load_from_dict(cls, data: Dict, **kwargs) -> "ManagedIdentityConfiguration": + from azure.ai.ml._schema.job.identity import ManagedIdentitySchema + + return ManagedIdentitySchema().load(data) + def __eq__(self, other: object) -> bool: if not isinstance(other, ManagedIdentityConfiguration): return NotImplemented @@ -440,6 +475,17 @@ def _to_job_rest_object(self) -> RestUserIdentity: def _from_job_rest_object(cls, obj: RestUserIdentity) -> "UserIdentity": return cls() + def _to_dict(self) -> Dict: + from azure.ai.ml._schema.job.identity import UserIdentitySchema + + return UserIdentitySchema().dump(self) + + @classmethod + def _load_from_dict(cls, data: Dict, **kwargs) -> "UserIdentityConfiguration": + from azure.ai.ml._schema.job.identity import UserIdentitySchema + + return UserIdentitySchema().load(data) + def __eq__(self, other: object) -> bool: if not isinstance(other, UserIdentityConfiguration): return NotImplemented @@ -457,6 +503,17 @@ def __init__(self): def _to_job_rest_object(self) -> RestAmlToken: return RestAmlToken() + def _to_dict(self) -> Dict: + from azure.ai.ml._schema.job.identity import AMLTokenIdentitySchema + + return AMLTokenIdentitySchema().dump(self) + + @classmethod + def _load_from_dict(cls, data: Dict, **kwargs) -> "AMLTokenIdentitySchema": + from azure.ai.ml._schema.job.identity import AMLTokenIdentitySchema + + return AMLTokenIdentitySchema().load(data) + @classmethod # pylint: disable=unused-argument def _from_job_rest_object(cls, obj: RestAmlToken) -> "AmlTokenConfiguration": diff --git a/sdk/ml/azure-ai-ml/tests/dsl/e2etests/test_dsl_pipeline.py b/sdk/ml/azure-ai-ml/tests/dsl/e2etests/test_dsl_pipeline.py index f3d2e65555ed..14488d7d2402 100644 --- a/sdk/ml/azure-ai-ml/tests/dsl/e2etests/test_dsl_pipeline.py +++ b/sdk/ml/azure-ai-ml/tests/dsl/e2etests/test_dsl_pipeline.py @@ -16,7 +16,7 @@ TensorFlowDistribution, command, dsl, - load_component, + load_component, AmlTokenConfiguration, UserIdentityConfiguration, ManagedIdentityConfiguration, ) from azure.ai.ml._utils._arm_id_utils import is_ARM_id_for_resource from azure.ai.ml.constants._common import AssetTypes, InputOutputModes @@ -2433,3 +2433,82 @@ def pipeline_with_default_component(): pipeline_job = client.jobs.create_or_update(pipeline_with_default_component()) created_pipeline_job: PipelineJob = client.jobs.get(pipeline_job.name) assert created_pipeline_job.jobs["node1"].component == f"{component_name}@default" + + def test_pipeline_node_identity_with_component(self, client: MLClient): + path = "./tests/test_configs/components/helloworld_component.yml" + component_func = load_component(path) + + @dsl.pipeline + def pipeline_func(component_in_path): + node1 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node1.identity = AmlTokenConfiguration() + + node2 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node2.identity = UserIdentityConfiguration() + + node3 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node3.identity = ManagedIdentityConfiguration() + + pipeline = pipeline_func(component_in_path=job_input) + pipeline_job = client.jobs.create_or_update(pipeline, compute="cpu-cluster") + omit_fields = [ + "jobs.*.componentId", + "jobs.*._source" + ] + actual_dict = omit_with_wildcard(pipeline_job._to_rest_object().as_dict()["properties"], *omit_fields) + assert actual_dict["jobs"] == { + 'node1': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'aml_token'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node1', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'node2': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'user_identity'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node2', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'node3': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'managed_identity'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node3', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'} + } diff --git a/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_command_builder.py b/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_command_builder.py index f5e0496e6d57..62172834438f 100644 --- a/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_command_builder.py +++ b/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_command_builder.py @@ -13,13 +13,15 @@ command, load_component, load_job, - spark, + spark, UserIdentityConfiguration, ) +from azure.ai.ml.dsl import pipeline from azure.ai.ml.entities import CommandJobLimits, JobResourceConfiguration from azure.ai.ml.entities._builders import Command from azure.ai.ml.entities._job.job_service import JobService as JobService from azure.ai.ml.entities._job.pipeline._component_translatable import ComponentTranslatableMixin from azure.ai.ml.exceptions import JobException, ValidationException +from test_utilities.utils import omit_with_wildcard from .._util import _DSL_TIMEOUT_SECOND @@ -954,3 +956,48 @@ def test_command_hash(self, test_command_params): node5 = command(**test_command_params, is_deterministic=False) assert hash(node1) != hash(node5) + + def test_pipeline_node_identity_with_builder(self, test_command_params): + test_command_params["identity"] = UserIdentityConfiguration() + command_node = command(**test_command_params) + rest_dict = command_node._to_rest_object() + assert rest_dict["identity"] == {'type': 'user_identity'} + + @pipeline + def my_pipeline(): + command_node() + + pipeline_job = my_pipeline() + omit_fields = [ + "jobs.*.componentId", + "jobs.*._source" + ] + actual_dict = omit_with_wildcard(pipeline_job._to_rest_object().as_dict()["properties"], *omit_fields) + + assert actual_dict["jobs"] == { + 'my_job': {'computeId': 'cpu-cluster', + 'display_name': 'my-fancy-job', + 'distribution': {'distribution_type': 'Mpi', + 'process_count_per_instance': 4}, + 'environment_variables': {'foo': 'bar'}, + 'identity': {'type': 'user_identity'}, + 'inputs': {'boolean': {'job_input_type': 'literal', + 'value': 'False'}, + 'float': {'job_input_type': 'literal', 'value': '0.01'}, + 'integer': {'job_input_type': 'literal', 'value': '1'}, + 'string': {'job_input_type': 'literal', 'value': 'str'}, + 'uri_file': {'job_input_type': 'uri_file', + 'mode': 'Download', + 'uri': 'https://my-blob/path/to/data'}, + 'uri_folder': {'job_input_type': 'uri_folder', + 'mode': 'ReadOnlyMount', + 'uri': 'https://my-blob/path/to/data'}}, + 'limits': None, + 'name': 'my_job', + 'outputs': {'my_model': {'job_output_type': 'mlflow_model', + 'mode': 'ReadWriteMount'}}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'} + } \ No newline at end of file diff --git a/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_dsl_pipeline.py b/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_dsl_pipeline.py index ddfe39ca2884..aeeb7f4a7c4a 100644 --- a/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_dsl_pipeline.py +++ b/sdk/ml/azure-ai-ml/tests/dsl/unittests/test_dsl_pipeline.py @@ -9,7 +9,8 @@ from test_configs.dsl_pipeline import data_binding_expression from test_utilities.utils import omit_with_wildcard, prepare_dsl_curated -from azure.ai.ml import Input, MLClient, MpiDistribution, Output, command, dsl, load_component, load_job, spark +from azure.ai.ml import Input, MLClient, MpiDistribution, Output, command, dsl, load_component, load_job, spark, \ + AmlTokenConfiguration, UserIdentityConfiguration, ManagedIdentityConfiguration from azure.ai.ml._restclient.v2022_05_01.models import ComponentContainerData, ComponentContainerDetails, SystemData from azure.ai.ml.constants._common import ( AZUREML_PRIVATE_FEATURES_ENV_VAR, @@ -214,21 +215,21 @@ def test_dsl_pipeline_complex_input_output(self) -> None: @dsl.pipeline() def pipeline( - job_in_data_name_version_def_mode, - job_in_data_name_version_mode_mount, - job_in_data_name_version_mode_download, - job_in_data_by_name, - job_in_data_by_armid, - job_in_data_by_store_path, - job_in_data_by_path_default_store, - job_in_data_by_store_path_and_mount, - job_in_data_by_store_path_and_download, - job_in_data_by_blob_dir, - job_in_data_by_blob_file, - job_in_data_local_dir, - job_in_data_local_file, - job_in_data_local_yaml_definition, - job_in_data_uri, + job_in_data_name_version_def_mode, + job_in_data_name_version_mode_mount, + job_in_data_name_version_mode_download, + job_in_data_by_name, + job_in_data_by_armid, + job_in_data_by_store_path, + job_in_data_by_path_default_store, + job_in_data_by_store_path_and_mount, + job_in_data_by_store_path_and_download, + job_in_data_by_blob_dir, + job_in_data_by_blob_file, + job_in_data_local_dir, + job_in_data_local_file, + job_in_data_local_yaml_definition, + job_in_data_uri, ): component_func = load_component(source=yaml_file) multiple_data_component = component_func( @@ -730,8 +731,8 @@ def pipeline(component_in_number, component_in_path): with pytest.raises(UserErrorException) as ex: pipeline(10, test_job_input) assert ( - "Pipeline input expected an azure.ai.ml.Input or primitive types (str, bool, int or float), but got type ." - in ex.__str__() + "Pipeline input expected an azure.ai.ml.Input or primitive types (str, bool, int or float), but got type ." + in ex.__str__() ) def test_dsl_pipeline_multi_times(self): @@ -766,8 +767,8 @@ def mock_add_to_builder(component): _add_component_to_current_definition_builder(component) with mock.patch( - "azure.ai.ml.dsl._pipeline_component_builder._add_component_to_current_definition_builder", - side_effect=mock_add_to_builder, + "azure.ai.ml.dsl._pipeline_component_builder._add_component_to_current_definition_builder", + side_effect=mock_add_to_builder, ) as mocker: # DSL yaml_file = "./tests/test_configs/components/helloworld_component.yml" @@ -877,12 +878,12 @@ def mock_from_rest(*args, **kwargs): component_names = set() with mock.patch( - "azure.ai.ml.operations._operation_orchestrator.OperationOrchestrator.get_asset_arm_id", - side_effect=mock_arm_id, + "azure.ai.ml.operations._operation_orchestrator.OperationOrchestrator.get_asset_arm_id", + side_effect=mock_arm_id, ): with mock.patch( - "azure.ai.ml._restclient.v2022_05_01.operations.ComponentVersionsOperations.create_or_update", - side_effect=mock_create, + "azure.ai.ml._restclient.v2022_05_01.operations.ComponentVersionsOperations.create_or_update", + side_effect=mock_create, ): with mock.patch.object(Component, "_from_rest_object", side_effect=mock_from_rest): for _, job in pipeline.jobs.items(): @@ -1050,56 +1051,56 @@ def pipeline(number, path): with patch("sys.stdout", new=StringIO()) as std_out: print(pipeline1) assert ( - "display_name: pipeline\ntype: pipeline\ninputs:\n number: 10\n path:\n type: uri_folder" - in std_out.getvalue() + "display_name: pipeline\ntype: pipeline\ninputs:\n number: 10\n path:\n type: uri_folder" + in std_out.getvalue() ) @pytest.mark.parametrize( "target_yml, target_dsl_pipeline", [ ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_basic.yml", - data_binding_expression.input_basic(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_basic.yml", + data_binding_expression.input_basic(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_literal_cross_type.yml", - data_binding_expression.input_literal_cross_type(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_literal_cross_type.yml", + data_binding_expression.input_literal_cross_type(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_literal_meta.yml", - data_binding_expression.input_literal_meta(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_literal_meta.yml", + data_binding_expression.input_literal_meta(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_path_concatenate.yml", - data_binding_expression.input_path_concatenate(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_path_concatenate.yml", + data_binding_expression.input_path_concatenate(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_reason_expression.yml", - data_binding_expression.input_reason_expression(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_reason_expression.yml", + data_binding_expression.input_reason_expression(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_string_concatenate.yml", - data_binding_expression.input_string_concatenate(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_string_concatenate.yml", + data_binding_expression.input_string_concatenate(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_compute.yml", - data_binding_expression.run_settings_compute(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_compute.yml", + data_binding_expression.run_settings_compute(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/input_path.yml", - data_binding_expression.input_path(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/input_path.yml", + data_binding_expression.input_path(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_choice.yml", - data_binding_expression.run_settings_sweep_choice(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_choice.yml", + data_binding_expression.run_settings_sweep_choice(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_limits.yml", - data_binding_expression.run_settings_sweep_limits(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_limits.yml", + data_binding_expression.run_settings_sweep_limits(), ), ( - "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_literal.yml", - data_binding_expression.run_settings_sweep_literal(), + "./tests/test_configs/dsl_pipeline/data_binding_expression/run_settings_sweep_literal.yml", + data_binding_expression.run_settings_sweep_literal(), ), ], ) @@ -1128,7 +1129,6 @@ def test_dsl_pipeline_support_data_binding_for_fields(self) -> None: dumped = schema.dump(distribution) assert dumped == {"type": "mpi", "process_count_per_instance": "${{parent.inputs.test}}"} - def test_dsl_pipeline_without_setting_binding_node(self) -> None: from dsl_pipeline.pipeline_with_set_binding_output_input.pipeline import pipeline_without_setting_binding_node @@ -1701,9 +1701,9 @@ def concatenation_in_pipeline(str_param: str): pipeline = concatenation_in_pipeline(str_param="string value") for node_name, expected_value in ( - ("microsoft_samples_echo_string", "${{parent.inputs.str_param}} right"), - ("microsoft_samples_echo_string_1", "left ${{parent.inputs.str_param}}"), - ("microsoft_samples_echo_string_2", "${{parent.inputs.str_param}}${{parent.inputs.str_param}}"), + ("microsoft_samples_echo_string", "${{parent.inputs.str_param}} right"), + ("microsoft_samples_echo_string_1", "left ${{parent.inputs.str_param}}"), + ("microsoft_samples_echo_string_2", "${{parent.inputs.str_param}}${{parent.inputs.str_param}}"), ): assert pipeline.jobs[node_name].inputs.component_in_string._data == expected_value @@ -1941,3 +1941,82 @@ def pipeline_func(component_in_path): pipeline_job = pipeline_func(component_in_path=Data(name="test", version="1", type=AssetTypes.MLTABLE)) result = pipeline_job._validate() assert result._to_dict() == {"result": "Succeeded"} + + def test_pipeline_node_identity_with_component(self): + path = "./tests/test_configs/components/helloworld_component.yml" + component_func = load_component(path) + + @dsl.pipeline + def pipeline_func(component_in_path): + node1 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node1.identity = AmlTokenConfiguration() + + node2 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node2.identity = UserIdentityConfiguration() + + node3 = component_func( + component_in_number=1, component_in_path=component_in_path + ) + node3.identity = ManagedIdentityConfiguration() + + pipeline = pipeline_func(component_in_path=Data(name="test", version="1", type=AssetTypes.MLTABLE)) + omit_fields = [ + "jobs.*.componentId", + "jobs.*._source" + ] + actual_dict = omit_with_wildcard(pipeline._to_rest_object().as_dict()["properties"], *omit_fields) + + assert actual_dict["jobs"] == { + 'node1': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'aml_token'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node1', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'node2': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'identity': {'type': 'user_identity'}, + 'environment_variables': {}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node2', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'node3': {'computeId': None, + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'managed_identity'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '1'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.component_in_path}}'}}, + 'limits': None, + 'name': 'node3', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'} + } diff --git a/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py b/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py index 065c5fa64194..e31d4030a5f0 100644 --- a/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py +++ b/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py @@ -1469,3 +1469,6 @@ def test_pipeline_node_default_output(self): # data-binding-expression with pytest.raises(ValidationException, match=" does not support setting path."): pipeline.jobs["merge_component_outputs"].outputs["component_out_path_1"].path = "xxx" + + def test_pipeline_node_with_identity(self): + pass diff --git a/sdk/ml/azure-ai-ml/tests/recordings/dsl/e2etests/test_dsl_pipeline.pyTestDSLPipelinetest_pipeline_node_identity_with_component.json b/sdk/ml/azure-ai-ml/tests/recordings/dsl/e2etests/test_dsl_pipeline.pyTestDSLPipelinetest_pipeline_node_identity_with_component.json new file mode 100644 index 000000000000..81520c9ce5d2 --- /dev/null +++ b/sdk/ml/azure-ai-ml/tests/recordings/dsl/e2etests/test_dsl_pipeline.pyTestDSLPipelinetest_pipeline_node_identity_with_component.json @@ -0,0 +1,754 @@ +{ + "Entries": [ + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster?api-version=2022-01-01-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Encoding": "gzip", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:21 GMT", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-96ad1d13a1fc5263ef2f679ca9dcef77-2bba3950f2dc775f-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "Transfer-Encoding": "chunked", + "Vary": [ + "Accept-Encoding", + "Accept-Encoding" + ], + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "a5d00617-cd04-4ac3-ad34-b9a4151e73d5", + "x-ms-ratelimit-remaining-subscription-reads": "11999", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100921Z:a5d00617-cd04-4ac3-ad34-b9a4151e73d5", + "x-request-time": "0.244" + }, + "ResponseBody": { + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster", + "name": "cpu-cluster", + "type": "Microsoft.MachineLearningServices/workspaces/computes", + "location": "centraluseuap", + "tags": {}, + "properties": { + "createdOn": "2022-09-22T09:02:22.1899959\u002B00:00", + "modifiedOn": "2022-09-23T03:28:18.0066218\u002B00:00", + "disableLocalAuth": false, + "description": null, + "resourceId": null, + "computeType": "AmlCompute", + "computeLocation": "centraluseuap", + "provisioningState": "Succeeded", + "provisioningErrors": null, + "isAttachedCompute": false, + "properties": { + "vmSize": "STANDARD_DS2_V2", + "vmPriority": "Dedicated", + "scaleSettings": { + "maxNodeCount": 4, + "minNodeCount": 1, + "nodeIdleTimeBeforeScaleDown": "PT2M" + }, + "subnet": null, + "currentNodeCount": 4, + "targetNodeCount": 4, + "nodeStateCounts": { + "preparingNodeCount": 0, + "runningNodeCount": 4, + "idleNodeCount": 0, + "unusableNodeCount": 0, + "leavingNodeCount": 0, + "preemptedNodeCount": 0 + }, + "allocationState": "Steady", + "allocationStateTransitionTime": "2022-10-21T06:50:04.626\u002B00:00", + "errors": null, + "remoteLoginPortPublicAccess": "Enabled", + "osType": "Linux", + "virtualMachineImage": null, + "isolatedNetwork": false, + "propertyBag": {} + } + } + } + }, + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore?api-version=2022-05-01", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Encoding": "gzip", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:24 GMT", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-6402a0f5a7ec946529d64bcff3eb3458-0978f43645bc59a0-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "Transfer-Encoding": "chunked", + "Vary": [ + "Accept-Encoding", + "Accept-Encoding" + ], + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "a90494e1-8637-4a22-a135-979d7856a0ce", + "x-ms-ratelimit-remaining-subscription-reads": "11998", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100924Z:a90494e1-8637-4a22-a135-979d7856a0ce", + "x-request-time": "0.125" + }, + "ResponseBody": { + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", + "name": "workspaceblobstore", + "type": "Microsoft.MachineLearningServices/workspaces/datastores", + "properties": { + "description": null, + "tags": null, + "properties": null, + "isDefault": true, + "credentials": { + "credentialsType": "AccountKey" + }, + "datastoreType": "AzureBlob", + "accountName": "sagvgsoim6nmhbq", + "containerName": "azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8", + "endpoint": "core.windows.net", + "protocol": "https", + "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity" + }, + "systemData": { + "createdAt": "2022-09-22T09:02:03.2629568\u002B00:00", + "createdBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", + "createdByType": "Application", + "lastModifiedAt": "2022-09-22T09:02:04.166989\u002B00:00", + "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", + "lastModifiedByType": "Application" + } + } + }, + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore/listSecrets?api-version=2022-05-01", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "0", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Encoding": "gzip", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:25 GMT", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-144635559263ab88d747fed9c72a79ed-692785d1cf4584e1-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "Transfer-Encoding": "chunked", + "Vary": "Accept-Encoding", + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "587bdc9a-a639-43e5-bd59-4495e68b6be6", + "x-ms-ratelimit-remaining-subscription-writes": "1199", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100925Z:587bdc9a-a639-43e5-bd59-4495e68b6be6", + "x-request-time": "0.462" + }, + "ResponseBody": { + "secretsType": "AccountKey", + "key": "dGhpcyBpcyBmYWtlIGtleQ==" + } + }, + { + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", + "RequestMethod": "HEAD", + "RequestHeaders": { + "Accept": "application/xml", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Fri, 21 Oct 2022 10:09:24 GMT", + "x-ms-version": "2021-08-06" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Accept-Ranges": "bytes", + "Content-Length": "35", + "Content-MD5": "L/DnSpFIn\u002BjaQWc\u002BsUQdcw==", + "Content-Type": "application/octet-stream", + "Date": "Fri, 21 Oct 2022 10:09:26 GMT", + "ETag": "\u00220x8DA9D48E17467D7\u0022", + "Last-Modified": "Fri, 23 Sep 2022 09:49:17 GMT", + "Server": [ + "Windows-Azure-Blob/1.0", + "Microsoft-HTTPAPI/2.0" + ], + "Vary": "Origin", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-creation-time": "Fri, 23 Sep 2022 09:49:16 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-meta-name": "9c9cfba9-82bd-45db-ad06-07009d1d9672", + "x-ms-meta-upload_status": "completed", + "x-ms-meta-version": "1", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-08-06" + }, + "ResponseBody": null + }, + { + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/az-ml-artifacts/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", + "RequestMethod": "HEAD", + "RequestHeaders": { + "Accept": "application/xml", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Fri, 21 Oct 2022 10:09:26 GMT", + "x-ms-version": "2021-08-06" + }, + "RequestBody": null, + "StatusCode": 404, + "ResponseHeaders": { + "Date": "Fri, 21 Oct 2022 10:09:26 GMT", + "Server": [ + "Windows-Azure-Blob/1.0", + "Microsoft-HTTPAPI/2.0" + ], + "Transfer-Encoding": "chunked", + "Vary": "Origin", + "x-ms-error-code": "BlobNotFound", + "x-ms-version": "2021-08-06" + }, + "ResponseBody": null + }, + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1?api-version=2022-05-01", + "RequestMethod": "PUT", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "288", + "Content-Type": "application/json", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": { + "properties": { + "properties": { + "hash_sha256": "0000000000000", + "hash_version": "0000000000000" + }, + "isAnonymous": true, + "isArchived": false, + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000" + } + }, + "StatusCode": 200, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Encoding": "gzip", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:29 GMT", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-f263dc62548de7b55c578859f274fe4b-3cb9e6099347e550-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "Transfer-Encoding": "chunked", + "Vary": [ + "Accept-Encoding", + "Accept-Encoding" + ], + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "c1f4663c-c196-4750-a964-f2ea65a1c6be", + "x-ms-ratelimit-remaining-subscription-writes": "1199", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100929Z:c1f4663c-c196-4750-a964-f2ea65a1c6be", + "x-request-time": "1.567" + }, + "ResponseBody": { + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", + "name": "1", + "type": "Microsoft.MachineLearningServices/workspaces/codes/versions", + "properties": { + "description": null, + "tags": {}, + "properties": { + "hash_sha256": "0000000000000", + "hash_version": "0000000000000" + }, + "isArchived": false, + "isAnonymous": false, + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000" + }, + "systemData": { + "createdAt": "2022-09-23T09:49:20.984936\u002B00:00", + "createdBy": "Ying Chen", + "createdByType": "User", + "lastModifiedAt": "2022-10-21T10:09:29.2216703\u002B00:00", + "lastModifiedBy": "Han Wang", + "lastModifiedByType": "User" + } + } + }, + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/000000000000000000000?api-version=2022-05-01", + "RequestMethod": "PUT", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "1301", + "Content-Type": "application/json", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": { + "properties": { + "description": "This is the basic command component", + "properties": {}, + "tags": { + "tag": "tagvalue", + "owner": "sdkteam" + }, + "isAnonymous": true, + "isArchived": false, + "componentSpec": { + "command": "echo Hello World \u0026 echo $[[${{inputs.component_in_number}}]] \u0026 echo ${{inputs.component_in_path}} \u0026 echo ${{outputs.component_out_path}} \u003E ${{outputs.component_out_path}}/component_in_number", + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", + "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:1", + "name": "azureml_anonymous", + "description": "This is the basic command component", + "tags": { + "tag": "tagvalue", + "owner": "sdkteam" + }, + "version": "000000000000000000000", + "$schema": "https://azuremlschemas.azureedge.net/development/commandComponent.schema.json", + "display_name": "CommandComponentBasic", + "is_deterministic": true, + "inputs": { + "component_in_number": { + "type": "number", + "optional": true, + "default": "10.99", + "description": "A number" + }, + "component_in_path": { + "type": "uri_folder", + "description": "A path" + } + }, + "outputs": { + "component_out_path": { + "type": "uri_folder" + } + }, + "type": "command", + "_source": "YAML.COMPONENT" + } + } + }, + "StatusCode": 201, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Length": "2310", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:31 GMT", + "Expires": "-1", + "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/000000000000000000000?api-version=2022-05-01", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-8897686a9d4d4d93152b9473e3a9624c-edd8adcbe9cba6e7-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "4550fab0-a432-4f3c-a1aa-1584049f98b3", + "x-ms-ratelimit-remaining-subscription-writes": "1198", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100932Z:4550fab0-a432-4f3c-a1aa-1584049f98b3", + "x-request-time": "2.342" + }, + "ResponseBody": { + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "name": "22d9f47b-7b67-4892-b37b-31357606ad9a", + "type": "Microsoft.MachineLearningServices/workspaces/components/versions", + "properties": { + "description": null, + "tags": { + "tag": "tagvalue", + "owner": "sdkteam" + }, + "properties": {}, + "isArchived": false, + "isAnonymous": true, + "componentSpec": { + "name": "azureml_anonymous", + "version": "22d9f47b-7b67-4892-b37b-31357606ad9a", + "display_name": "CommandComponentBasic", + "is_deterministic": "True", + "type": "command", + "description": "This is the basic command component", + "tags": { + "tag": "tagvalue", + "owner": "sdkteam" + }, + "inputs": { + "component_in_path": { + "type": "uri_folder", + "optional": "False", + "description": "A path" + }, + "component_in_number": { + "type": "number", + "optional": "True", + "default": "10.99", + "description": "A number" + } + }, + "outputs": { + "component_out_path": { + "type": "uri_folder" + } + }, + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", + "environment": "azureml://registries/azureml-dev/environments/AzureML-sklearn-0.24-ubuntu18.04-py37-cpu/versions/1", + "resources": { + "instance_count": "1" + }, + "command": "echo Hello World \u0026 echo $[[${{inputs.component_in_number}}]] \u0026 echo ${{inputs.component_in_path}} \u0026 echo ${{outputs.component_out_path}} \u003E ${{outputs.component_out_path}}/component_in_number", + "$schema": "https://azuremlschemas.azureedge.net/development/commandComponent.schema.json" + } + }, + "systemData": { + "createdAt": "2022-10-12T02:55:05.0682179\u002B00:00", + "createdBy": "Xingzhi Zhang", + "createdByType": "User", + "lastModifiedAt": "2022-10-12T02:55:05.5746553\u002B00:00", + "lastModifiedBy": "Xingzhi Zhang", + "lastModifiedByType": "User" + } + } + }, + { + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/000000000000000000000?api-version=2022-10-01-preview", + "RequestMethod": "PUT", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "2585", + "Content-Type": "application/json", + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" + }, + "RequestBody": { + "properties": { + "properties": {}, + "tags": {}, + "computeId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster", + "displayName": "pipeline_func", + "experimentName": "azure-ai-ml", + "isArchived": false, + "jobType": "Pipeline", + "inputs": { + "component_in_path": { + "uri": "https://dprepdata.blob.core.windows.net/demo/Titanic.csv", + "jobInputType": "uri_file" + } + }, + "jobs": { + "node1": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node1", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "aml_token" + } + }, + "node2": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node2", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "user_identity" + } + }, + "node3": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node3", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "managed_identity" + } + } + }, + "outputs": {}, + "settings": { + "_source": "DSL" + } + } + }, + "StatusCode": 201, + "ResponseHeaders": { + "Cache-Control": "no-cache", + "Content-Length": "5260", + "Content-Type": "application/json; charset=utf-8", + "Date": "Fri, 21 Oct 2022 10:09:42 GMT", + "Expires": "-1", + "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/000000000000000000000?api-version=2022-10-01-preview", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", + "Server-Timing": "traceparent;desc=\u002200-7737e5868135aef13cb2828459e2df5d-de11e78ffbc856ef-01\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "x-aml-cluster": "vienna-test-westus2-02", + "X-Content-Type-Options": "nosniff", + "x-ms-correlation-request-id": "aab355a4-1bce-4126-a57e-012982746f49", + "x-ms-ratelimit-remaining-subscription-writes": "1197", + "x-ms-response-type": "standard", + "x-ms-routing-request-id": "JAPANEAST:20221021T100943Z:aab355a4-1bce-4126-a57e-012982746f49", + "x-request-time": "5.323" + }, + "ResponseBody": { + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/000000000000000000000", + "name": "000000000000000000000", + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "properties": { + "description": null, + "tags": {}, + "properties": { + "azureml.DevPlatv2": "true", + "azureml.runsource": "azureml.PipelineRun", + "runSource": "MFE", + "runType": "HTTP", + "azureml.parameters": "{}", + "azureml.continue_on_step_failure": "False", + "azureml.continue_on_failed_optional_input": "True", + "azureml.defaultComputeName": "cpu-cluster", + "azureml.defaultDataStoreName": "workspaceblobstore", + "azureml.pipelineComponent": "pipelinerun" + }, + "displayName": "pipeline_func", + "status": "Running", + "experimentName": "azure-ai-ml", + "services": { + "Tracking": { + "jobServiceType": "Tracking", + "port": null, + "endpoint": "azureml://master.api.azureml-test.ms/mlflow/v1.0/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000?", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + }, + "Studio": { + "jobServiceType": "Studio", + "port": null, + "endpoint": "https://ml.azure.com/runs/000000000000000000000?wsid=/subscriptions/00000000-0000-0000-0000-000000000/resourcegroups/00000/workspaces/00000", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + } + }, + "computeId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster", + "isArchived": false, + "identity": null, + "componentId": null, + "jobType": "Pipeline", + "settings": { + "_source": "DSL" + }, + "jobs": { + "node1": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node1", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "aml_token" + } + }, + "node2": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node2", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "user_identity" + } + }, + "node3": { + "resources": null, + "distribution": null, + "limits": null, + "environment_variables": {}, + "name": "node3", + "type": "command", + "display_name": null, + "tags": {}, + "computeId": null, + "inputs": { + "component_in_path": { + "job_input_type": "literal", + "value": "${{parent.inputs.component_in_path}}" + }, + "component_in_number": { + "job_input_type": "literal", + "value": "1" + } + }, + "outputs": {}, + "properties": {}, + "_source": "YAML.COMPONENT", + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/22d9f47b-7b67-4892-b37b-31357606ad9a", + "identity": { + "type": "managed_identity" + } + } + }, + "inputs": { + "component_in_path": { + "description": null, + "uri": "https://dprepdata.blob.core.windows.net/demo/Titanic.csv", + "mode": "ReadOnlyMount", + "jobInputType": "uri_file" + } + }, + "outputs": {}, + "sourceJobId": null + }, + "systemData": { + "createdAt": "2022-10-21T10:09:41.075458\u002B00:00", + "createdBy": "Han Wang", + "createdByType": "User" + } + } + } + ], + "Variables": {} +} From c79b90721e56210111a2e616e3e982d7199873d2 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 21 Oct 2022 18:21:03 +0800 Subject: [PATCH 2/5] add test --- .../ai/ml/_schema/pipeline/component_job.py | 7 + .../azure/ai/ml/entities/_job/command_job.py | 1 + .../unittests/test_pipeline_job_entity.py | 228 +++++++++++------- .../helloworld_pipeline_job_with_identity.yml | 53 ++++ 4 files changed, 205 insertions(+), 84 deletions(-) create mode 100644 sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_identity.yml diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/_schema/pipeline/component_job.py b/sdk/ml/azure-ai-ml/azure/ai/ml/_schema/pipeline/component_job.py index b89cbe644b24..b928a61bc8be 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/_schema/pipeline/component_job.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/_schema/pipeline/component_job.py @@ -144,6 +144,13 @@ class CommandSchema(BaseNodeSchema, ParameterizedCommandSchema): ], ) services = fields.Dict(keys=fields.Str(), values=NestedField(JobServiceSchema)) + identity = UnionField( + [ + NestedField(ManagedIdentitySchema), + NestedField(AMLTokenIdentitySchema), + NestedField(UserIdentitySchema), + ] + ) @post_load def make(self, data, **kwargs) -> "Command": diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/command_job.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/command_job.py index 53bdc4e54a25..027299b82b1d 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/command_job.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/command_job.py @@ -261,6 +261,7 @@ def _to_node(self, context: Dict = None, **kwargs): limits=self.limits, services=self.services, properties=self.properties, + identity=self.identity, ) def _validate(self) -> None: diff --git a/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py b/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py index e31d4030a5f0..841b9108d61e 100644 --- a/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py +++ b/sdk/ml/azure-ai-ml/tests/pipeline_job/unittests/test_pipeline_job_entity.py @@ -6,7 +6,7 @@ import yaml from marshmallow import ValidationError from pytest_mock import MockFixture -from test_utilities.utils import verify_entity_load_and_dump +from test_utilities.utils import verify_entity_load_and_dump, omit_with_wildcard from azure.ai.ml import MLClient, load_job from azure.ai.ml._restclient.v2022_02_01_preview.models import JobBaseData as FebRestJob @@ -161,16 +161,16 @@ def test_automl_node_in_pipeline_forecasting(self, mock_machinelearning_client: "rest_job_file, node_name", [ ( - "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_regression.json", - "hello_automl_regression", + "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_regression.json", + "hello_automl_regression", ), ( - "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/rest_pipeline_with_automl_output_binding.json", - "classification_node", + "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/rest_pipeline_with_automl_output_binding.json", + "classification_node", ), ( - "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/rest_pipeline_with_automl_output.json", - "hello_automl_regression", + "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/rest_pipeline_with_automl_output.json", + "hello_automl_regression", ), ], ) @@ -344,7 +344,7 @@ def test_pipeline_job_automl_regression_output(self, mock_machinelearning_client } def test_automl_node_in_pipeline_text_classification( - self, mock_machinelearning_client: MLClient, mocker: MockFixture + self, mock_machinelearning_client: MLClient, mocker: MockFixture ): test_path = "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_text_classification.yml" job = load_job(source=test_path) @@ -376,7 +376,7 @@ def test_automl_node_in_pipeline_text_classification( } def test_automl_node_in_pipeline_text_classification_multilabel( - self, mock_machinelearning_client: MLClient, mocker: MockFixture + self, mock_machinelearning_client: MLClient, mocker: MockFixture ): test_path = ( "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_text_classification_multilabel.yml" @@ -440,11 +440,11 @@ def test_automl_node_in_pipeline_text_ner(self, mock_machinelearning_client: MLC @pytest.mark.parametrize("run_type", ["single", "sweep", "automode"]) def test_automl_node_in_pipeline_image_multiclass_classification( - self, - mock_machinelearning_client: MLClient, - mocker: MockFixture, - run_type: str, - tmp_path: Path, + self, + mock_machinelearning_client: MLClient, + mocker: MockFixture, + run_type: str, + tmp_path: Path, ): test_path = "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_image_multiclass_classification.yml" @@ -517,11 +517,11 @@ def test_automl_node_in_pipeline_image_multiclass_classification( @pytest.mark.parametrize("run_type", ["single", "sweep", "automode"]) def test_automl_node_in_pipeline_image_multilabel_classification( - self, - mock_machinelearning_client: MLClient, - mocker: MockFixture, - run_type: str, - tmp_path: Path, + self, + mock_machinelearning_client: MLClient, + mocker: MockFixture, + run_type: str, + tmp_path: Path, ): test_path = "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_image_multilabel_classification.yml" @@ -594,7 +594,7 @@ def test_automl_node_in_pipeline_image_multilabel_classification( @pytest.mark.parametrize("run_type", ["single", "sweep", "automode"]) def test_automl_node_in_pipeline_image_object_detection( - self, mock_machinelearning_client: MLClient, mocker: MockFixture, run_type: str, tmp_path: Path + self, mock_machinelearning_client: MLClient, mocker: MockFixture, run_type: str, tmp_path: Path ): test_path = "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_image_object_detection.yml" @@ -668,11 +668,11 @@ def test_automl_node_in_pipeline_image_object_detection( @pytest.mark.parametrize("run_type", ["single", "sweep", "automode"]) def test_automl_node_in_pipeline_image_instance_segmentation( - self, - mock_machinelearning_client: MLClient, - mocker: MockFixture, - run_type: str, - tmp_path: Path, + self, + mock_machinelearning_client: MLClient, + mocker: MockFixture, + run_type: str, + tmp_path: Path, ): test_path = ( "./tests/test_configs/pipeline_jobs/jobs_with_automl_nodes/onejob_automl_image_instance_segmentation.yml" @@ -873,8 +873,8 @@ def test_default_user_identity_if_empty_identity_input(self): "_source": "YAML.JOB", "archives": None, "args": "--input1 ${{inputs.input1}} --output2 " - "${{outputs.output1}} --my_sample_rate " - "${{inputs.sample_rate}}", + "${{outputs.output1}} --my_sample_rate " + "${{inputs.sample_rate}}", "computeId": None, "conf": { "spark.driver.cores": 1, @@ -910,7 +910,7 @@ def test_default_user_identity_if_empty_identity_input(self): } def test_spark_node_in_pipeline_with_dynamic_allocation_disabled( - self, + self, ): test_path = "./tests/test_configs/pipeline_jobs/invalid/pipeline_job_with_spark_job_with_dynamic_allocation_disabled.yml" job = load_job(test_path) @@ -919,7 +919,7 @@ def test_spark_node_in_pipeline_with_dynamic_allocation_disabled( assert ve.message == "Should not specify min or max executors when dynamic allocation is disabled." def test_spark_node_in_pipeline_with_invalid_code( - self, + self, ): test_path = "./tests/test_configs/pipeline_jobs/invalid/pipeline_job_with_spark_job_with_invalid_code.yml" job = load_job(test_path) @@ -928,85 +928,85 @@ def test_spark_node_in_pipeline_with_invalid_code( assert ve.message == "Entry doesn't exist" def test_spark_node_in_pipeline_with_git_code( - self, + self, ): test_path = "./tests/test_configs/pipeline_jobs/invalid/pipeline_job_with_spark_job_with_git_code.yml" job = load_job(test_path) job._validate() def test_infer_pipeline_output_type_as_node_type( - self, + self, ) -> None: pipeline_job = load_job( source="./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_defaults_with_parallel_job_tabular_input_e2e.yml", ) assert ( - pipeline_job.jobs["hello_world_inline_parallel_tabular_job_1"].outputs["job_output_file"].type - == AssetTypes.URI_FILE + pipeline_job.jobs["hello_world_inline_parallel_tabular_job_1"].outputs["job_output_file"].type + == AssetTypes.URI_FILE ) @pytest.mark.parametrize( "pipeline_job_path, expected_type, expected_components", [ ( - "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_literal_output_binding_to_inline_job_input.yml", - "uri_folder", - { - "score_job": { - "_source": "YAML.JOB", - "command": 'echo "hello" && echo "world" && echo "train" > world.txt', - "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", - "inputs": {"model_input": {"type": "uri_folder"}, "test_data": {"type": "uri_folder"}}, - "is_deterministic": True, - "outputs": {"score_output": {"type": "uri_folder"}}, - "tags": {}, - "type": "command", - "version": "1", + "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_literal_output_binding_to_inline_job_input.yml", + "uri_folder", + { + "score_job": { + "_source": "YAML.JOB", + "command": 'echo "hello" && echo "world" && echo "train" > world.txt', + "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", + "inputs": {"model_input": {"type": "uri_folder"}, "test_data": {"type": "uri_folder"}}, + "is_deterministic": True, + "outputs": {"score_output": {"type": "uri_folder"}}, + "tags": {}, + "type": "command", + "version": "1", + }, }, - }, ), ( - "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_literal_output_binding_to_inline_job_input2.yml", - "mltable", - { - "score_job": { - "_source": "YAML.JOB", - "command": 'echo "hello" && echo "world" && echo "train" > world.txt', - "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", - "inputs": {"model_input": {"type": "mltable"}, "test_data": {"type": "uri_folder"}}, - "is_deterministic": True, - "outputs": {"score_output": {"type": "uri_folder"}}, - "tags": {}, - "type": "command", - "version": "1", + "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_literal_output_binding_to_inline_job_input2.yml", + "mltable", + { + "score_job": { + "_source": "YAML.JOB", + "command": 'echo "hello" && echo "world" && echo "train" > world.txt', + "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", + "inputs": {"model_input": {"type": "mltable"}, "test_data": {"type": "uri_folder"}}, + "is_deterministic": True, + "outputs": {"score_output": {"type": "uri_folder"}}, + "tags": {}, + "type": "command", + "version": "1", + }, }, - }, ), ( - "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_output_binding_to_inline_job_input.yml", - "uri_folder", - { - "score_job": { - "_source": "YAML.JOB", - "command": 'echo "hello" && echo "world" && echo "train" > world.txt', - "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", - "inputs": {"model_input": {"type": "uri_folder"}, "test_data": {"type": "uri_folder"}}, - "is_deterministic": True, - "outputs": {"score_output": {"type": "uri_folder"}}, - "tags": {}, - "type": "command", - "version": "1", + "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_registered_component_output_binding_to_inline_job_input.yml", + "uri_folder", + { + "score_job": { + "_source": "YAML.JOB", + "command": 'echo "hello" && echo "world" && echo "train" > world.txt', + "environment": "azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:5", + "inputs": {"model_input": {"type": "uri_folder"}, "test_data": {"type": "uri_folder"}}, + "is_deterministic": True, + "outputs": {"score_output": {"type": "uri_folder"}}, + "tags": {}, + "type": "command", + "version": "1", + }, }, - }, ), ], ) def test_pipeline_job_with_inline_command_job_input_binding_to_registered_component_job_output( - self, - client: MLClient, - pipeline_job_path: str, - expected_type, - expected_components, + self, + client: MLClient, + pipeline_job_path: str, + expected_type, + expected_components, ) -> None: pipeline_job = load_job( source=pipeline_job_path, @@ -1084,7 +1084,7 @@ def test_pipeline_without_setting_binding_node(self, mock_machinelearning_client } def test_pipeline_with_only_setting_pipeline_level( - self, mock_machinelearning_client: MLClient, mocker: MockFixture + self, mock_machinelearning_client: MLClient, mocker: MockFixture ): test_path = "./tests/test_configs/dsl_pipeline/pipeline_with_set_binding_output_input/pipeline_with_only_setting_pipeline_level.yml" job = load_job(source=test_path) @@ -1214,7 +1214,7 @@ def test_pipeline_with_only_setting_binding_node(self, mock_machinelearning_clie } def test_pipeline_with_setting_binding_node_and_pipeline_level( - self, mock_machinelearning_client: MLClient, mocker: MockFixture + self, mock_machinelearning_client: MLClient, mocker: MockFixture ): test_path = "./tests/test_configs/dsl_pipeline/pipeline_with_set_binding_output_input/pipeline_with_setting_binding_node_and_pipeline_level.yml" job = load_job(source=test_path) @@ -1282,7 +1282,7 @@ def test_pipeline_with_setting_binding_node_and_pipeline_level( } def test_pipeline_with_inline_job_setting_binding_node_and_pipeline_level( - self, mock_machinelearning_client: MLClient, mocker: MockFixture + self, mock_machinelearning_client: MLClient, mocker: MockFixture ): test_path = "./tests/test_configs/dsl_pipeline/pipeline_with_set_binding_output_input/pipeline_with_inline_job_setting_binding_node_and_pipeline_level.yml" job = load_job(source=test_path) @@ -1471,4 +1471,64 @@ def test_pipeline_node_default_output(self): pipeline.jobs["merge_component_outputs"].outputs["component_out_path_1"].path = "xxx" def test_pipeline_node_with_identity(self): - pass + test_path = "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_identity.yml" + pipeline_job: PipelineJob = load_job(source=test_path) + + omit_fields = [ + "jobs.*.componentId", + "jobs.*._source" + ] + actual_dict = omit_with_wildcard(pipeline_job._to_rest_object().as_dict()["properties"], *omit_fields) + assert actual_dict["jobs"] == { + 'hello_world_component': { + 'computeId': 'cpu-cluster', + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'user_identity'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_number}}'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_path}}'}}, + 'limits': None, + 'name': 'hello_world_component', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'hello_world_component_2': { + 'computeId': 'cpu-cluster', + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'aml_token'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_other_number}}'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_path}}'}}, + 'limits': None, + 'name': 'hello_world_component_2', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'}, + 'hello_world_component_3': { + 'computeId': 'cpu-cluster', + 'display_name': None, + 'distribution': None, + 'environment_variables': {}, + 'identity': {'type': 'user_identity'}, + 'inputs': {'component_in_number': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_other_number}}'}, + 'component_in_path': {'job_input_type': 'literal', + 'value': '${{parent.inputs.job_in_path}}'}}, + 'limits': None, + 'name': 'hello_world_component_3', + 'outputs': {}, + 'properties': {}, + 'resources': None, + 'tags': {}, + 'type': 'command'} + } diff --git a/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_identity.yml b/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_identity.yml new file mode 100644 index 000000000000..227a23bdf617 --- /dev/null +++ b/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_identity.yml @@ -0,0 +1,53 @@ +type: pipeline + +# name: microsoft.samples.PipelineJobSampleToDefineScope #follow up on schema validation error +name: simplepipelinejob +description: The hello world pipeline job +tags: + tag: tagvalue + owner: sdkteam + +# Check if supported ... +experiment_name: my_first_experiment + +compute: azureml:cpu-cluster + +inputs: + # examples of inputs that take values such as int, string, etc. + job_in_number: 10 + job_in_other_number: + value: 15 + job_in_path: + path: ../data + mode: ro_mount + +jobs: + hello_world_component: + type: command + component: azureml:microsoftsamplesCommandComponentBasic_second:1 + compute: azureml:cpu-cluster + inputs: + component_in_number: ${{parent.inputs.job_in_number}} + component_in_path: ${{parent.inputs.job_in_path}} + identity: + type: user_identity + + hello_world_component_2: + type: command + component: azureml:microsoftsamplesCommandComponentBasic_second:1 + compute: azureml:cpu-cluster + inputs: + component_in_number: ${{parent.inputs.job_in_other_number}} + component_in_path: ${{parent.inputs.job_in_path}} + identity: + type: aml_token + + hello_world_component_3: + type: command + compute: azureml:cpu-cluster + inputs: + component_in_number: ${{parent.inputs.job_in_other_number}} + component_in_path: ${{parent.inputs.job_in_path}} + identity: + type: user_identity + command: echo "hello world" \ No newline at end of file From 73141bc24a58e33cabba04dcd13da02ea6195d04 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 24 Oct 2022 12:10:10 +0800 Subject: [PATCH 3/5] update --- .../azure/ai/ml/entities/_credentials.py | 9 +- ...th_command_job_with_dataset_short_uri.json | 384 +++++++++--------- ...efaults_with_command_job_e2e_short_uri.yml | 2 +- 3 files changed, 202 insertions(+), 193 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py index 626c5388a546..83f8fe10c105 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py @@ -8,7 +8,7 @@ from typing import List, Dict, Union from azure.ai.ml._azure_environments import _get_active_directory_url_from_metadata -from azure.ai.ml._utils.utils import camel_to_snake, snake_to_pascal +from azure.ai.ml._utils.utils import camel_to_snake, snake_to_pascal, snake_to_camel from azure.ai.ml.constants._common import CommonYamlFields from azure.ai.ml.entities._mixins import RestTranslatableMixin, DictMixin, YamlTranslatableMixin from azure.ai.ml._restclient.v2022_05_01.models import ( @@ -349,11 +349,12 @@ def _load( data: Dict = None, ) -> Union["ManagedIdentityConfiguration", "UserIdentityConfiguration", "AmlTokenConfiguration"]: type_str = data.get(CommonYamlFields.TYPE) - if type_str == camel_to_snake(ConnectionAuthType.MANAGED_IDENTITY): + type_str = snake_to_camel(type_str) + if type_str == ConnectionAuthType.MANAGED_IDENTITY: identity_cls = ManagedIdentityConfiguration - elif type_str == camel_to_snake(IdentityConfigurationType.USER_IDENTITY): + elif type_str == IdentityConfigurationType.USER_IDENTITY: identity_cls = UserIdentityConfiguration - elif type_str == camel_to_snake(IdentityConfigurationType.AML_TOKEN): + elif type_str == IdentityConfigurationType.AML_TOKEN: identity_cls = AmlTokenConfiguration else: msg = f"Unsupported identity type: {type_str}." diff --git a/sdk/ml/azure-ai-ml/tests/recordings/pipeline_job/e2etests/test_pipeline_job.pyTestPipelineJobtest_pipeline_job_with_command_job_with_dataset_short_uri.json b/sdk/ml/azure-ai-ml/tests/recordings/pipeline_job/e2etests/test_pipeline_job.pyTestPipelineJobtest_pipeline_job_with_command_job_with_dataset_short_uri.json index 68bdd0ee8b49..c1f2f22e493a 100644 --- a/sdk/ml/azure-ai-ml/tests/recordings/pipeline_job/e2etests/test_pipeline_job.pyTestPipelineJobtest_pipeline_job_with_command_job_with_dataset_short_uri.json +++ b/sdk/ml/azure-ai-ml/tests/recordings/pipeline_job/e2etests/test_pipeline_job.pyTestPipelineJobtest_pipeline_job_with_command_job_with_dataset_short_uri.json @@ -7,7 +7,7 @@ "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -15,24 +15,24 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:10 GMT", + "Date": "Mon, 24 Oct 2022 03:59:01 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-964cdeb16294bdadef5519aa6d40a32d-5ec564f5ddd332ca-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-16871457f8d69b5b681a01b69cf8af05-50a3d458754f67e4-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ "Accept-Encoding", "Accept-Encoding" ], - "x-aml-cluster": "vienna-test-westus2-01", + "x-aml-cluster": "vienna-test-westus2-02", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "33486a26-f0c1-4e77-8538-b9aea231aa02", - "x-ms-ratelimit-remaining-subscription-reads": "11991", + "x-ms-correlation-request-id": "4b0f73b8-0ed2-4d1e-b273-6da295d45285", + "x-ms-ratelimit-remaining-subscription-reads": "11999", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222811Z:33486a26-f0c1-4e77-8538-b9aea231aa02", - "x-request-time": "0.265" + "x-ms-routing-request-id": "JAPANEAST:20221024T035901Z:4b0f73b8-0ed2-4d1e-b273-6da295d45285", + "x-request-time": "0.225" }, "ResponseBody": { "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster", @@ -41,8 +41,8 @@ "location": "centraluseuap", "tags": {}, "properties": { - "createdOn": "2022-09-29T22:16:14.236098\u002B00:00", - "modifiedOn": "2022-09-29T22:17:32.3214572\u002B00:00", + "createdOn": "2022-09-22T09:02:22.1899959\u002B00:00", + "modifiedOn": "2022-09-23T03:28:18.0066218\u002B00:00", "disableLocalAuth": false, "description": null, "resourceId": null, @@ -56,22 +56,22 @@ "vmPriority": "Dedicated", "scaleSettings": { "maxNodeCount": 4, - "minNodeCount": 0, + "minNodeCount": 1, "nodeIdleTimeBeforeScaleDown": "PT2M" }, "subnet": null, - "currentNodeCount": 0, - "targetNodeCount": 0, + "currentNodeCount": 4, + "targetNodeCount": 4, "nodeStateCounts": { "preparingNodeCount": 0, - "runningNodeCount": 0, + "runningNodeCount": 4, "idleNodeCount": 0, "unusableNodeCount": 0, "leavingNodeCount": 0, "preemptedNodeCount": 0 }, "allocationState": "Steady", - "allocationStateTransitionTime": "2022-09-29T22:17:29.635\u002B00:00", + "allocationStateTransitionTime": "2022-10-21T06:50:04.626\u002B00:00", "errors": null, "remoteLoginPortPublicAccess": "Enabled", "osType": "Linux", @@ -89,7 +89,7 @@ "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -97,24 +97,24 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:11 GMT", + "Date": "Mon, 24 Oct 2022 03:59:02 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-483def58952a9f11da9ac2a2129c5985-46790bfa2b84f306-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-32663827de67c8d4b240edb975310ac6-54b4eb3b9e5c9e04-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ "Accept-Encoding", "Accept-Encoding" ], - "x-aml-cluster": "vienna-test-westus2-01", + "x-aml-cluster": "vienna-test-westus2-02", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "382b286c-8170-4eda-afa0-7081bd0c230e", - "x-ms-ratelimit-remaining-subscription-reads": "11990", + "x-ms-correlation-request-id": "14cd9574-1612-4193-b21c-2fe0c6131d94", + "x-ms-ratelimit-remaining-subscription-reads": "11998", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222811Z:382b286c-8170-4eda-afa0-7081bd0c230e", - "x-request-time": "0.250" + "x-ms-routing-request-id": "JAPANEAST:20221024T035902Z:14cd9574-1612-4193-b21c-2fe0c6131d94", + "x-request-time": "0.219" }, "ResponseBody": { "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/computes/cpu-cluster", @@ -123,8 +123,8 @@ "location": "centraluseuap", "tags": {}, "properties": { - "createdOn": "2022-09-29T22:16:14.236098\u002B00:00", - "modifiedOn": "2022-09-29T22:17:32.3214572\u002B00:00", + "createdOn": "2022-09-22T09:02:22.1899959\u002B00:00", + "modifiedOn": "2022-09-23T03:28:18.0066218\u002B00:00", "disableLocalAuth": false, "description": null, "resourceId": null, @@ -138,22 +138,22 @@ "vmPriority": "Dedicated", "scaleSettings": { "maxNodeCount": 4, - "minNodeCount": 0, + "minNodeCount": 1, "nodeIdleTimeBeforeScaleDown": "PT2M" }, "subnet": null, - "currentNodeCount": 0, - "targetNodeCount": 0, + "currentNodeCount": 4, + "targetNodeCount": 4, "nodeStateCounts": { "preparingNodeCount": 0, - "runningNodeCount": 0, + "runningNodeCount": 4, "idleNodeCount": 0, "unusableNodeCount": 0, "leavingNodeCount": 0, "preemptedNodeCount": 0 }, "allocationState": "Steady", - "allocationStateTransitionTime": "2022-09-29T22:17:29.635\u002B00:00", + "allocationStateTransitionTime": "2022-10-21T06:50:04.626\u002B00:00", "errors": null, "remoteLoginPortPublicAccess": "Enabled", "osType": "Linux", @@ -171,7 +171,7 @@ "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -179,11 +179,11 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:12 GMT", + "Date": "Mon, 24 Oct 2022 03:59:05 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-d1033387cfab0814b51f10c089f8ffb6-f4389d1eaea0973c-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-d12f6cd9be493da737296299eb3e88e0-10936133c338bc38-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ @@ -192,11 +192,11 @@ ], "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "b9e0a1aa-9794-48b9-808e-b0be0c043a14", - "x-ms-ratelimit-remaining-subscription-reads": "11989", + "x-ms-correlation-request-id": "1eacb179-063d-4147-a5aa-1d7e5220c4a4", + "x-ms-ratelimit-remaining-subscription-reads": "11997", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222812Z:b9e0a1aa-9794-48b9-808e-b0be0c043a14", - "x-request-time": "0.087" + "x-ms-routing-request-id": "JAPANEAST:20221024T035905Z:1eacb179-063d-4147-a5aa-1d7e5220c4a4", + "x-request-time": "0.127" }, "ResponseBody": { "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", @@ -211,17 +211,17 @@ "credentialsType": "AccountKey" }, "datastoreType": "AzureBlob", - "accountName": "sas3vrosykmdp4s", - "containerName": "azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1", + "accountName": "sagvgsoim6nmhbq", + "containerName": "azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8", "endpoint": "core.windows.net", "protocol": "https", "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity" }, "systemData": { - "createdAt": "2022-09-29T22:16:05.5940148\u002B00:00", + "createdAt": "2022-09-22T09:02:03.2629568\u002B00:00", "createdBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", "createdByType": "Application", - "lastModifiedAt": "2022-09-29T22:16:06.5431636\u002B00:00", + "lastModifiedAt": "2022-09-22T09:02:04.166989\u002B00:00", "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", "lastModifiedByType": "Application" } @@ -235,7 +235,7 @@ "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Content-Length": "0", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -243,21 +243,21 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:12 GMT", + "Date": "Mon, 24 Oct 2022 03:59:06 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-f9c279591ba798a871d8b1667ac34da8-ed24cda77308526b-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-c3f3777351be3d439074626737417904-b9ff861c390c1035-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": "Accept-Encoding", "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "dcda370a-dcf7-4958-9674-84aba18e74fc", - "x-ms-ratelimit-remaining-subscription-writes": "1194", + "x-ms-correlation-request-id": "83bf03fd-a240-488b-9621-5fd82110f9f6", + "x-ms-ratelimit-remaining-subscription-writes": "1199", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222813Z:dcda370a-dcf7-4958-9674-84aba18e74fc", - "x-request-time": "0.098" + "x-ms-routing-request-id": "JAPANEAST:20221024T035906Z:83bf03fd-a240-488b-9621-5fd82110f9f6", + "x-request-time": "0.134" }, "ResponseBody": { "secretsType": "AccountKey", @@ -265,15 +265,15 @@ } }, { - "RequestUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000/python/sample1.csv", + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000/python/sample1.csv", "RequestMethod": "HEAD", "RequestHeaders": { "Accept": "application/xml", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azsdk-python-storage-blob/12.9.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)", - "x-ms-date": "Thu, 29 Sep 2022 22:28:13 GMT", - "x-ms-version": "2020-10-02" + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Mon, 24 Oct 2022 03:59:05 GMT", + "x-ms-version": "2021-08-06" }, "RequestBody": null, "StatusCode": 200, @@ -282,9 +282,9 @@ "Content-Length": "508", "Content-MD5": "dUQjYq1qrTeqLOaZ4N2AUQ==", "Content-Type": "application/octet-stream", - "Date": "Thu, 29 Sep 2022 22:28:12 GMT", - "ETag": "\u00220x8DAA269D12CDADC\u0022", - "Last-Modified": "Thu, 29 Sep 2022 22:27:39 GMT", + "Date": "Mon, 24 Oct 2022 03:59:07 GMT", + "ETag": "\u00220x8DA9D482EE600C0\u0022", + "Last-Modified": "Fri, 23 Sep 2022 09:44:17 GMT", "Server": [ "Windows-Azure-Blob/1.0", "Microsoft-HTTPAPI/2.0" @@ -293,32 +293,32 @@ "x-ms-access-tier": "Hot", "x-ms-access-tier-inferred": "true", "x-ms-blob-type": "BlockBlob", - "x-ms-creation-time": "Thu, 29 Sep 2022 22:27:38 GMT", + "x-ms-creation-time": "Fri, 23 Sep 2022 09:44:17 GMT", "x-ms-lease-state": "available", "x-ms-lease-status": "unlocked", - "x-ms-meta-name": "000000000000000000000", + "x-ms-meta-name": "92e51c4c-40c7-4f95-ba55-e3a63d7d7c14", "x-ms-meta-upload_status": "completed", "x-ms-meta-version": "1", "x-ms-server-encrypted": "true", - "x-ms-version": "2020-10-02" + "x-ms-version": "2021-08-06" }, "ResponseBody": null }, { - "RequestUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/az-ml-artifacts/00000000000000000000000000000000/python/sample1.csv", + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/az-ml-artifacts/00000000000000000000000000000000/python/sample1.csv", "RequestMethod": "HEAD", "RequestHeaders": { "Accept": "application/xml", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azsdk-python-storage-blob/12.9.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)", - "x-ms-date": "Thu, 29 Sep 2022 22:28:13 GMT", - "x-ms-version": "2020-10-02" + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Mon, 24 Oct 2022 03:59:06 GMT", + "x-ms-version": "2021-08-06" }, "RequestBody": null, "StatusCode": 404, "ResponseHeaders": { - "Date": "Thu, 29 Sep 2022 22:28:12 GMT", + "Date": "Mon, 24 Oct 2022 03:59:07 GMT", "Server": [ "Windows-Azure-Blob/1.0", "Microsoft-HTTPAPI/2.0" @@ -326,12 +326,12 @@ "Transfer-Encoding": "chunked", "Vary": "Origin", "x-ms-error-code": "BlobNotFound", - "x-ms-version": "2020-10-02" + "x-ms-version": "2021-08-06" }, "ResponseBody": null }, { - "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/000000000000000000000/versions/1?api-version=2022-05-01", + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/92e51c4c-40c7-4f95-ba55-e3a63d7d7c14/versions/1?api-version=2022-05-01", "RequestMethod": "PUT", "RequestHeaders": { "Accept": "application/json", @@ -339,7 +339,7 @@ "Connection": "keep-alive", "Content-Length": "295", "Content-Type": "application/json", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": { "properties": { @@ -349,7 +349,7 @@ }, "isAnonymous": true, "isArchived": false, - "codeUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000/python" + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000/python" } }, "StatusCode": 200, @@ -357,11 +357,11 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:13 GMT", + "Date": "Mon, 24 Oct 2022 03:59:10 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-5470592d6496e54ed92bad27657b3b9b-08d28ad77bf9936a-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-6943e1d3077ce3c4e0ff738d1b7c9e06-36d7706cbff6ea51-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ @@ -370,14 +370,14 @@ ], "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "5ee17dae-a562-47cf-bff7-e35bf7564fba", - "x-ms-ratelimit-remaining-subscription-writes": "1191", + "x-ms-correlation-request-id": "24df3eb1-6164-46c9-8c81-5598bc6a9b47", + "x-ms-ratelimit-remaining-subscription-writes": "1199", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222813Z:5ee17dae-a562-47cf-bff7-e35bf7564fba", - "x-request-time": "0.187" + "x-ms-routing-request-id": "JAPANEAST:20221024T035910Z:24df3eb1-6164-46c9-8c81-5598bc6a9b47", + "x-request-time": "1.448" }, "ResponseBody": { - "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/000000000000000000000/versions/1", + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/92e51c4c-40c7-4f95-ba55-e3a63d7d7c14/versions/1", "name": "1", "type": "Microsoft.MachineLearningServices/workspaces/codes/versions", "properties": { @@ -389,14 +389,14 @@ }, "isArchived": false, "isAnonymous": false, - "codeUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000/python" + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000/python" }, "systemData": { - "createdAt": "2022-09-29T22:27:39.9285536\u002B00:00", - "createdBy": "Aditi Singhal", + "createdAt": "2022-09-23T09:44:19.3941658\u002B00:00", + "createdBy": "Ying Chen", "createdByType": "User", - "lastModifiedAt": "2022-09-29T22:28:13.5967027\u002B00:00", - "lastModifiedBy": "Aditi Singhal", + "lastModifiedAt": "2022-10-24T03:59:10.7175169\u002B00:00", + "lastModifiedBy": "Han Wang", "lastModifiedByType": "User" } } @@ -408,9 +408,9 @@ "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "Content-Length": "876", + "Content-Length": "891", "Content-Type": "application/json", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": { "properties": { @@ -421,7 +421,7 @@ "isArchived": false, "componentSpec": { "command": "pip freeze \u0026\u0026 echo Hello World", - "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/000000000000000000000/versions/1", + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/92e51c4c-40c7-4f95-ba55-e3a63d7d7c14/versions/1", "environment": "azureml:AzureML-Minimal:1", "name": "azureml_anonymous", "description": "Train a model on the Iris dataset-1.", @@ -453,26 +453,26 @@ "StatusCode": 201, "ResponseHeaders": { "Cache-Control": "no-cache", - "Content-Length": "1874", + "Content-Length": "1888", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:16 GMT", + "Date": "Mon, 24 Oct 2022 03:59:14 GMT", "Expires": "-1", "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/000000000000000000000?api-version=2022-05-01", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-c2dce5e4122080c0fe6ba038a03ec70e-93f4b08063d3234c-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-2c8d7f11b4edcc15aba5ea15f6636924-ad4cf05d9abf9512-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "d264355f-861c-48d1-b24c-30961f2df3b4", - "x-ms-ratelimit-remaining-subscription-writes": "1190", + "x-ms-correlation-request-id": "c1f954aa-fdc7-4ff8-bc5f-ffab9a5a9ded", + "x-ms-ratelimit-remaining-subscription-writes": "1198", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222817Z:d264355f-861c-48d1-b24c-30961f2df3b4", - "x-request-time": "3.651" + "x-ms-routing-request-id": "JAPANEAST:20221024T035914Z:c1f954aa-fdc7-4ff8-bc5f-ffab9a5a9ded", + "x-request-time": "2.769" }, "ResponseBody": { - "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/5c097fc6-8b13-451b-8347-02ebb1c8cf2c", - "name": "5c097fc6-8b13-451b-8347-02ebb1c8cf2c", + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/c221e141-f8c1-465c-bb35-bf37cc1a9c77", + "name": "c221e141-f8c1-465c-bb35-bf37cc1a9c77", "type": "Microsoft.MachineLearningServices/workspaces/components/versions", "properties": { "description": null, @@ -482,7 +482,7 @@ "isAnonymous": true, "componentSpec": { "name": "azureml_anonymous", - "version": "5c097fc6-8b13-451b-8347-02ebb1c8cf2c", + "version": "c221e141-f8c1-465c-bb35-bf37cc1a9c77", "display_name": "hello_world_inline_commandjob_1", "is_deterministic": "True", "type": "command", @@ -503,7 +503,7 @@ "type": "uri_folder" } }, - "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/000000000000000000000/versions/1", + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/92e51c4c-40c7-4f95-ba55-e3a63d7d7c14/versions/1", "environment": "azureml://registries/azureml-dev/environments/AzureML-Minimal/versions/1", "resources": { "instance_count": "1" @@ -513,11 +513,11 @@ } }, "systemData": { - "createdAt": "2022-09-29T22:28:16.9814957\u002B00:00", - "createdBy": "Aditi Singhal", + "createdAt": "2022-10-12T03:02:13.658895\u002B00:00", + "createdBy": "Xingzhi Zhang", "createdByType": "User", - "lastModifiedAt": "2022-09-29T22:28:16.9814957\u002B00:00", - "lastModifiedBy": "Aditi Singhal", + "lastModifiedAt": "2022-10-12T03:02:14.1196243\u002B00:00", + "lastModifiedBy": "Xingzhi Zhang", "lastModifiedByType": "User" } } @@ -529,7 +529,7 @@ "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -537,11 +537,11 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:17 GMT", + "Date": "Mon, 24 Oct 2022 03:59:14 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-dd5647b1f873d6bc038dc9aecf2ed7b6-cea01d831d9e6bbd-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-ea403bd6cfe90ee04c2e8a1aa01162d5-979ff442e7c7c854-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ @@ -550,11 +550,11 @@ ], "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "236a6b26-27fa-4f88-865c-bc7bd446df6c", - "x-ms-ratelimit-remaining-subscription-reads": "11988", + "x-ms-correlation-request-id": "d8608544-1419-4c71-ad70-01042eac5d4e", + "x-ms-ratelimit-remaining-subscription-reads": "11996", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222817Z:236a6b26-27fa-4f88-865c-bc7bd446df6c", - "x-request-time": "0.099" + "x-ms-routing-request-id": "JAPANEAST:20221024T035915Z:d8608544-1419-4c71-ad70-01042eac5d4e", + "x-request-time": "0.094" }, "ResponseBody": { "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", @@ -569,17 +569,17 @@ "credentialsType": "AccountKey" }, "datastoreType": "AzureBlob", - "accountName": "sas3vrosykmdp4s", - "containerName": "azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1", + "accountName": "sagvgsoim6nmhbq", + "containerName": "azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8", "endpoint": "core.windows.net", "protocol": "https", "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity" }, "systemData": { - "createdAt": "2022-09-29T22:16:05.5940148\u002B00:00", + "createdAt": "2022-09-22T09:02:03.2629568\u002B00:00", "createdBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", "createdByType": "Application", - "lastModifiedAt": "2022-09-29T22:16:06.5431636\u002B00:00", + "lastModifiedAt": "2022-09-22T09:02:04.166989\u002B00:00", "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", "lastModifiedByType": "Application" } @@ -593,7 +593,7 @@ "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Content-Length": "0", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": null, "StatusCode": 200, @@ -601,21 +601,21 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:17 GMT", + "Date": "Mon, 24 Oct 2022 03:59:15 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-66617321718381cd1c4be54c7a159758-44c1a6a12f79cb03-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-9fb92a5b876dc3806a787242a09de27d-d945c2d223a477ab-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": "Accept-Encoding", "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "fd7c43e4-c3b9-4e3d-b153-2d01eb59f524", - "x-ms-ratelimit-remaining-subscription-writes": "1193", + "x-ms-correlation-request-id": "0e151f9b-7a6c-4478-80e0-150357f12968", + "x-ms-ratelimit-remaining-subscription-writes": "1198", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222818Z:fd7c43e4-c3b9-4e3d-b153-2d01eb59f524", - "x-request-time": "0.102" + "x-ms-routing-request-id": "JAPANEAST:20221024T035915Z:0e151f9b-7a6c-4478-80e0-150357f12968", + "x-request-time": "0.100" }, "ResponseBody": { "secretsType": "AccountKey", @@ -623,15 +623,15 @@ } }, { - "RequestUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", "RequestMethod": "HEAD", "RequestHeaders": { "Accept": "application/xml", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azsdk-python-storage-blob/12.9.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)", - "x-ms-date": "Thu, 29 Sep 2022 22:28:18 GMT", - "x-ms-version": "2020-10-02" + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Mon, 24 Oct 2022 03:59:14 GMT", + "x-ms-version": "2021-08-06" }, "RequestBody": null, "StatusCode": 200, @@ -640,9 +640,9 @@ "Content-Length": "35", "Content-MD5": "L/DnSpFIn\u002BjaQWc\u002BsUQdcw==", "Content-Type": "application/octet-stream", - "Date": "Thu, 29 Sep 2022 22:28:18 GMT", - "ETag": "\u00220x8DAA269B39E05D8\u0022", - "Last-Modified": "Thu, 29 Sep 2022 22:26:49 GMT", + "Date": "Mon, 24 Oct 2022 03:59:15 GMT", + "ETag": "\u00220x8DA9D48E17467D7\u0022", + "Last-Modified": "Fri, 23 Sep 2022 09:49:17 GMT", "Server": [ "Windows-Azure-Blob/1.0", "Microsoft-HTTPAPI/2.0" @@ -651,32 +651,32 @@ "x-ms-access-tier": "Hot", "x-ms-access-tier-inferred": "true", "x-ms-blob-type": "BlockBlob", - "x-ms-creation-time": "Thu, 29 Sep 2022 22:26:49 GMT", + "x-ms-creation-time": "Fri, 23 Sep 2022 09:49:16 GMT", "x-ms-lease-state": "available", "x-ms-lease-status": "unlocked", - "x-ms-meta-name": "5559a10b-f428-4259-a127-d246099b26e8", + "x-ms-meta-name": "9c9cfba9-82bd-45db-ad06-07009d1d9672", "x-ms-meta-upload_status": "completed", "x-ms-meta-version": "1", "x-ms-server-encrypted": "true", - "x-ms-version": "2020-10-02" + "x-ms-version": "2021-08-06" }, "ResponseBody": null }, { - "RequestUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/az-ml-artifacts/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", + "RequestUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/az-ml-artifacts/00000000000000000000000000000000/COMPONENT_PLACEHOLDER", "RequestMethod": "HEAD", "RequestHeaders": { "Accept": "application/xml", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "User-Agent": "azsdk-python-storage-blob/12.9.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)", - "x-ms-date": "Thu, 29 Sep 2022 22:28:18 GMT", - "x-ms-version": "2020-10-02" + "User-Agent": "azsdk-python-storage-blob/12.13.1 Python/3.8.13 (Windows-10-10.0.19044-SP0)", + "x-ms-date": "Mon, 24 Oct 2022 03:59:14 GMT", + "x-ms-version": "2021-08-06" }, "RequestBody": null, "StatusCode": 404, "ResponseHeaders": { - "Date": "Thu, 29 Sep 2022 22:28:18 GMT", + "Date": "Mon, 24 Oct 2022 03:59:15 GMT", "Server": [ "Windows-Azure-Blob/1.0", "Microsoft-HTTPAPI/2.0" @@ -684,12 +684,12 @@ "Transfer-Encoding": "chunked", "Vary": "Origin", "x-ms-error-code": "BlobNotFound", - "x-ms-version": "2020-10-02" + "x-ms-version": "2021-08-06" }, "ResponseBody": null }, { - "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/5559a10b-f428-4259-a127-d246099b26e8/versions/1?api-version=2022-05-01", + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1?api-version=2022-05-01", "RequestMethod": "PUT", "RequestHeaders": { "Accept": "application/json", @@ -697,7 +697,7 @@ "Connection": "keep-alive", "Content-Length": "288", "Content-Type": "application/json", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": { "properties": { @@ -707,7 +707,7 @@ }, "isAnonymous": true, "isArchived": false, - "codeUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000" + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000" } }, "StatusCode": 200, @@ -715,11 +715,11 @@ "Cache-Control": "no-cache", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:18 GMT", + "Date": "Mon, 24 Oct 2022 03:59:16 GMT", "Expires": "-1", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-e935703a48e5842dbeb64aaae09d639b-43fb59b12313d9d8-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-dade0cde479120a863a2a07c93299744-9f5ddcdd303a4dfa-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Transfer-Encoding": "chunked", "Vary": [ @@ -728,14 +728,14 @@ ], "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "06bde0a3-7c63-46e6-a9fc-abb103a392f5", - "x-ms-ratelimit-remaining-subscription-writes": "1189", + "x-ms-correlation-request-id": "0b379b33-6629-494e-bc8f-4d9f3045eb8d", + "x-ms-ratelimit-remaining-subscription-writes": "1197", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222818Z:06bde0a3-7c63-46e6-a9fc-abb103a392f5", - "x-request-time": "0.193" + "x-ms-routing-request-id": "JAPANEAST:20221024T035916Z:0b379b33-6629-494e-bc8f-4d9f3045eb8d", + "x-request-time": "0.329" }, "ResponseBody": { - "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/5559a10b-f428-4259-a127-d246099b26e8/versions/1", + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", "name": "1", "type": "Microsoft.MachineLearningServices/workspaces/codes/versions", "properties": { @@ -747,14 +747,14 @@ }, "isArchived": false, "isAnonymous": false, - "codeUri": "https://sas3vrosykmdp4s.blob.core.windows.net/azureml-blobstore-86253a4f-a7a6-4008-8c86-ce9cf2978bc1/LocalUpload/00000000000000000000000000000000" + "codeUri": "https://sagvgsoim6nmhbq.blob.core.windows.net/azureml-blobstore-e61cd5e2-512f-475e-9842-5e2a973993b8/LocalUpload/00000000000000000000000000000000" }, "systemData": { - "createdAt": "2022-09-29T22:26:51.4133291\u002B00:00", - "createdBy": "Aditi Singhal", + "createdAt": "2022-09-23T09:49:20.984936\u002B00:00", + "createdBy": "Ying Chen", "createdByType": "User", - "lastModifiedAt": "2022-09-29T22:28:18.7300295\u002B00:00", - "lastModifiedBy": "Aditi Singhal", + "lastModifiedAt": "2022-10-24T03:59:16.5205573\u002B00:00", + "lastModifiedBy": "Han Wang", "lastModifiedByType": "User" } } @@ -768,7 +768,7 @@ "Connection": "keep-alive", "Content-Length": "789", "Content-Type": "application/json", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": { "properties": { @@ -779,7 +779,7 @@ "isArchived": false, "componentSpec": { "command": "echo Hello World", - "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/5559a10b-f428-4259-a127-d246099b26e8/versions/1", + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", "environment": "azureml:AzureML-Minimal:1", "name": "azureml_anonymous", "description": "Train a model on the Iris dataset-2.", @@ -802,26 +802,26 @@ "StatusCode": 201, "ResponseHeaders": { "Cache-Control": "no-cache", - "Content-Length": "1676", + "Content-Length": "1677", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:21 GMT", + "Date": "Mon, 24 Oct 2022 03:59:17 GMT", "Expires": "-1", "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/000000000000000000000?api-version=2022-05-01", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-ab515e61e47ce65f5572d5943e9dbc35-4616916f87e82c60-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-902ac0553b2f102af093a7e66ad263e6-87d3abc23414113d-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "d16231e7-4fcb-4263-bd74-a794f551284e", - "x-ms-ratelimit-remaining-subscription-writes": "1188", + "x-ms-correlation-request-id": "31dd46e8-98cf-48ef-b5b0-cacc43b64e11", + "x-ms-ratelimit-remaining-subscription-writes": "1196", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222822Z:d16231e7-4fcb-4263-bd74-a794f551284e", - "x-request-time": "3.493" + "x-ms-routing-request-id": "JAPANEAST:20221024T035918Z:31dd46e8-98cf-48ef-b5b0-cacc43b64e11", + "x-request-time": "1.063" }, "ResponseBody": { - "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/82975c6e-f34c-4a05-b1cd-70f5a7f022a4", - "name": "82975c6e-f34c-4a05-b1cd-70f5a7f022a4", + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/f26498aa-440d-4c1e-8909-f7f0c946131e", + "name": "f26498aa-440d-4c1e-8909-f7f0c946131e", "type": "Microsoft.MachineLearningServices/workspaces/components/versions", "properties": { "description": null, @@ -831,7 +831,7 @@ "isAnonymous": true, "componentSpec": { "name": "azureml_anonymous", - "version": "82975c6e-f34c-4a05-b1cd-70f5a7f022a4", + "version": "f26498aa-440d-4c1e-8909-f7f0c946131e", "display_name": "hello_world_inline_commandjob_2", "is_deterministic": "True", "type": "command", @@ -842,7 +842,7 @@ "optional": "False" } }, - "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/5559a10b-f428-4259-a127-d246099b26e8/versions/1", + "code": "azureml:/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/codes/9c9cfba9-82bd-45db-ad06-07009d1d9672/versions/1", "environment": "azureml://registries/azureml-dev/environments/AzureML-Minimal/versions/1", "resources": { "instance_count": "1" @@ -852,25 +852,25 @@ } }, "systemData": { - "createdAt": "2022-09-29T22:28:21.895777\u002B00:00", - "createdBy": "Aditi Singhal", + "createdAt": "2022-10-12T03:02:19.8596456\u002B00:00", + "createdBy": "Xingzhi Zhang", "createdByType": "User", - "lastModifiedAt": "2022-09-29T22:28:21.895777\u002B00:00", - "lastModifiedBy": "Aditi Singhal", + "lastModifiedAt": "2022-10-12T03:02:20.377037\u002B00:00", + "lastModifiedBy": "Xingzhi Zhang", "lastModifiedByType": "User" } } }, { - "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_751723769768?api-version=2022-06-01-preview", + "RequestUri": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_982795825197?api-version=2022-10-01-preview", "RequestMethod": "PUT", "RequestHeaders": { "Accept": "application/json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", - "Content-Length": "2359", + "Content-Length": "2394", "Content-Type": "application/json", - "User-Agent": "azure-ai-ml/0.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.5 (Windows-10-10.0.19041-SP0)" + "User-Agent": "azure-ai-ml/1.1.0 azsdk-python-mgmt-machinelearningservices/0.1.0 Python/3.8.13 (Windows-10-10.0.19044-SP0)" }, "RequestBody": { "properties": { @@ -880,7 +880,7 @@ "tag": "tagvalue", "owner": "sdkteam" }, - "displayName": "test_751723769768", + "displayName": "test_982795825197", "experimentName": "azure-ai-ml", "isArchived": false, "jobType": "Pipeline", @@ -920,7 +920,7 @@ }, "properties": {}, "_source": "YAML.JOB", - "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/5c097fc6-8b13-451b-8347-02ebb1c8cf2c" + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/c221e141-f8c1-465c-bb35-bf37cc1a9c77" }, "hello_world_inline_commandjob_2": { "resources": null, @@ -944,7 +944,10 @@ "test_property": "test_value" }, "_source": "YAML.JOB", - "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/82975c6e-f34c-4a05-b1cd-70f5a7f022a4" + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/f26498aa-440d-4c1e-8909-f7f0c946131e", + "identity": { + "type": "aml_token" + } } }, "outputs": { @@ -961,26 +964,26 @@ "StatusCode": 201, "ResponseHeaders": { "Cache-Control": "no-cache", - "Content-Length": "4777", + "Content-Length": "4881", "Content-Type": "application/json; charset=utf-8", - "Date": "Thu, 29 Sep 2022 22:28:29 GMT", + "Date": "Mon, 24 Oct 2022 03:59:28 GMT", "Expires": "-1", - "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_751723769768?api-version=2022-06-01-preview", + "Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_982795825197?api-version=2022-10-01-preview", "Pragma": "no-cache", "Request-Context": "appId=cid-v1:512cc15a-13b5-415b-bfd0-dce7accb6bb1", - "Server-Timing": "traceparent;desc=\u002200-b7ba2e15e59b7f53ce1efbc8f286cf41-cbb4230eb85d8fb5-01\u0022", + "Server-Timing": "traceparent;desc=\u002200-861e05190d7999271af48017b6ec2259-89b8de91c99d68af-00\u0022", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "x-aml-cluster": "vienna-test-westus2-01", "X-Content-Type-Options": "nosniff", - "x-ms-correlation-request-id": "50473c6b-9996-42df-b0a6-d94591cefb75", - "x-ms-ratelimit-remaining-subscription-writes": "1187", + "x-ms-correlation-request-id": "fa03d653-bffd-472f-9eb8-534d763472bc", + "x-ms-ratelimit-remaining-subscription-writes": "1195", "x-ms-response-type": "standard", - "x-ms-routing-request-id": "WESTUS2:20220929T222829Z:50473c6b-9996-42df-b0a6-d94591cefb75", - "x-request-time": "4.846" + "x-ms-routing-request-id": "JAPANEAST:20221024T035928Z:fa03d653-bffd-472f-9eb8-534d763472bc", + "x-request-time": "5.316" }, "ResponseBody": { - "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_751723769768", - "name": "test_751723769768", + "id": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/jobs/test_982795825197", + "name": "test_982795825197", "type": "Microsoft.MachineLearningServices/workspaces/jobs", "properties": { "description": "The hello world pipeline job with inline command job", @@ -999,7 +1002,7 @@ "azureml.defaultDataStoreName": "workspaceblobstore", "azureml.pipelineComponent": "pipelinerun" }, - "displayName": "test_751723769768", + "displayName": "test_982795825197", "status": "Preparing", "experimentName": "azure-ai-ml", "services": { @@ -1009,15 +1012,17 @@ "endpoint": "azureml://master.api.azureml-test.ms/mlflow/v1.0/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000?", "status": null, "errorMessage": null, - "properties": null + "properties": null, + "nodes": null }, "Studio": { "jobServiceType": "Studio", "port": null, - "endpoint": "https://ml.azure.com/runs/test_751723769768?wsid=/subscriptions/00000000-0000-0000-0000-000000000/resourcegroups/00000/workspaces/00000", + "endpoint": "https://ml.azure.com/runs/test_982795825197?wsid=/subscriptions/00000000-0000-0000-0000-000000000/resourcegroups/00000/workspaces/00000", "status": null, "errorMessage": null, - "properties": null + "properties": null, + "nodes": null } }, "computeId": null, @@ -1058,7 +1063,7 @@ }, "properties": {}, "_source": "YAML.JOB", - "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/5c097fc6-8b13-451b-8347-02ebb1c8cf2c" + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/c221e141-f8c1-465c-bb35-bf37cc1a9c77" }, "hello_world_inline_commandjob_2": { "resources": null, @@ -1082,7 +1087,10 @@ "test_property": "test_value" }, "_source": "YAML.JOB", - "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/82975c6e-f34c-4a05-b1cd-70f5a7f022a4" + "componentId": "/subscriptions/00000000-0000-0000-0000-000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/components/azureml_anonymous/versions/f26498aa-440d-4c1e-8909-f7f0c946131e", + "identity": { + "type": "aml_token" + } } }, "inputs": { @@ -1104,14 +1112,14 @@ "sourceJobId": null }, "systemData": { - "createdAt": "2022-09-29T22:28:28.7488562\u002B00:00", - "createdBy": "Aditi Singhal", + "createdAt": "2022-10-24T03:59:26.7346666\u002B00:00", + "createdBy": "Han Wang", "createdByType": "User" } } } ], "Variables": { - "name": "test_751723769768" + "name": "test_982795825197" } } diff --git a/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_defaults_with_command_job_e2e_short_uri.yml b/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_defaults_with_command_job_e2e_short_uri.yml index a24c3ce2a0e4..c3bd9cd5d0ca 100644 --- a/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_defaults_with_command_job_e2e_short_uri.yml +++ b/sdk/ml/azure-ai-ml/tests/test_configs/pipeline_jobs/helloworld_pipeline_job_defaults_with_command_job_e2e_short_uri.yml @@ -52,4 +52,4 @@ jobs: properties: test_property: test_value identity: - type: AMLToken + type: aml_token From 463e69bdd0de5d8ce3ff262a72beb76c8b0984b7 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 24 Oct 2022 12:44:32 +0800 Subject: [PATCH 4/5] fix pylint error --- .../azure-ai-ml/azure/ai/ml/entities/_credentials.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py index 83f8fe10c105..a70b5137483b 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py @@ -444,12 +444,14 @@ def _from_workspace_rest_object(cls, obj: RestUserAssignedIdentityConfiguration) ) def _to_dict(self) -> Dict: + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import ManagedIdentitySchema return ManagedIdentitySchema().dump(self) @classmethod - def _load_from_dict(cls, data: Dict, **kwargs) -> "ManagedIdentityConfiguration": + def _load_from_dict(cls, data: Dict) -> "ManagedIdentityConfiguration": + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import ManagedIdentitySchema return ManagedIdentitySchema().load(data) @@ -477,12 +479,14 @@ def _from_job_rest_object(cls, obj: RestUserIdentity) -> "UserIdentity": return cls() def _to_dict(self) -> Dict: + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import UserIdentitySchema return UserIdentitySchema().dump(self) @classmethod - def _load_from_dict(cls, data: Dict, **kwargs) -> "UserIdentityConfiguration": + def _load_from_dict(cls, data: Dict) -> "UserIdentityConfiguration": + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import UserIdentitySchema return UserIdentitySchema().load(data) @@ -505,12 +509,14 @@ def _to_job_rest_object(self) -> RestAmlToken: return RestAmlToken() def _to_dict(self) -> Dict: + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import AMLTokenIdentitySchema return AMLTokenIdentitySchema().dump(self) @classmethod - def _load_from_dict(cls, data: Dict, **kwargs) -> "AMLTokenIdentitySchema": + def _load_from_dict(cls, data: Dict) -> "AMLTokenIdentitySchema": + # pylint: disable=no-member from azure.ai.ml._schema.job.identity import AMLTokenIdentitySchema return AMLTokenIdentitySchema().load(data) From f1c09d3c28ed5846bdd0e4d5b7a7f11283eb2ea8 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 24 Oct 2022 14:17:37 +0800 Subject: [PATCH 5/5] fix test --- .../azure/ai/ml/constants/_common.py | 6 ++++++ .../azure/ai/ml/entities/_credentials.py | 17 ++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/constants/_common.py b/sdk/ml/azure-ai-ml/azure/ai/ml/constants/_common.py index 13e68037c07f..c459c43868f6 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/constants/_common.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/constants/_common.py @@ -571,3 +571,9 @@ class RollingRate: class Scope: SUBSCRIPTION="subscription" RESOURCE_GROUP="resource_group" + + +class IdentityType: + AML_TOKEN = "aml_token" + USER_IDENTITY = "user_identity" + MANAGED_IDENTITY = "managed_identity" diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py index a70b5137483b..5fc4adda9c12 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_credentials.py @@ -8,8 +8,8 @@ from typing import List, Dict, Union from azure.ai.ml._azure_environments import _get_active_directory_url_from_metadata -from azure.ai.ml._utils.utils import camel_to_snake, snake_to_pascal, snake_to_camel -from azure.ai.ml.constants._common import CommonYamlFields +from azure.ai.ml._utils.utils import camel_to_snake, snake_to_pascal +from azure.ai.ml.constants._common import CommonYamlFields, IdentityType from azure.ai.ml.entities._mixins import RestTranslatableMixin, DictMixin, YamlTranslatableMixin from azure.ai.ml._restclient.v2022_05_01.models import ( AccountKeyDatastoreCredentials as RestAccountKeyDatastoreCredentials, @@ -349,12 +349,11 @@ def _load( data: Dict = None, ) -> Union["ManagedIdentityConfiguration", "UserIdentityConfiguration", "AmlTokenConfiguration"]: type_str = data.get(CommonYamlFields.TYPE) - type_str = snake_to_camel(type_str) - if type_str == ConnectionAuthType.MANAGED_IDENTITY: + if type_str == IdentityType.MANAGED_IDENTITY: identity_cls = ManagedIdentityConfiguration - elif type_str == IdentityConfigurationType.USER_IDENTITY: + elif type_str == IdentityType.USER_IDENTITY: identity_cls = UserIdentityConfiguration - elif type_str == IdentityConfigurationType.AML_TOKEN: + elif type_str == IdentityType.AML_TOKEN: identity_cls = AmlTokenConfiguration else: msg = f"Unsupported identity type: {type_str}." @@ -381,7 +380,7 @@ def __init__( self, *, client_id: str = None, resource_id: str = None, object_id: str = None, principal_id: str = None ): super().__init__() - self.type = camel_to_snake(ConnectionAuthType.MANAGED_IDENTITY) + self.type = IdentityType.MANAGED_IDENTITY self.client_id = client_id # TODO: Check if both client_id and resource_id are required self.resource_id = resource_id @@ -467,7 +466,7 @@ class UserIdentityConfiguration(_BaseIdentityConfiguration): def __init__(self): super().__init__() - self.type = camel_to_snake(IdentityConfigurationType.USER_IDENTITY) + self.type = IdentityType.USER_IDENTITY # pylint: disable=no-self-use def _to_job_rest_object(self) -> RestUserIdentity: @@ -502,7 +501,7 @@ class AmlTokenConfiguration(_BaseIdentityConfiguration): def __init__(self): super().__init__() - self.type = camel_to_snake(IdentityConfigurationType.AML_TOKEN) + self.type = IdentityType.AML_TOKEN # pylint: disable=no-self-use def _to_job_rest_object(self) -> RestAmlToken: