From c1dd47fba8c2058a9a98c3ea6e1cb98740155ddf Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Sun, 3 Mar 2024 18:20:31 -0800 Subject: [PATCH 1/9] Remove Optional type annotation from get() methods --- .../azure/ai/ml/operations/_feature_set_operations.py | 4 +++- .../azure/ai/ml/operations/_feature_store_operations.py | 4 +++- .../azure/ai/ml/operations/_registry_operations.py | 4 +++- .../ai/ml/operations/_workspace_connections_operations.py | 4 +++- .../azure/ai/ml/operations/_workspace_hub_operation.py | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_set_operations.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_set_operations.py index a84528c24289..e471e67a1986 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_set_operations.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_set_operations.py @@ -125,7 +125,7 @@ def _get(self, name: str, version: Optional[str] = None, **kwargs: Dict) -> Feat @distributed_trace @monitor_with_activity(ops_logger, "FeatureSet.Get", ActivityType.PUBLICAPI) - def get(self, name: str, version: str, **kwargs: Dict) -> Optional[FeatureSet]: # type: ignore + def get(self, name: str, version: str, **kwargs: Dict) -> FeatureSet: # type: ignore """Get the specified FeatureSet asset. :param name: Name of FeatureSet asset. @@ -134,6 +134,8 @@ def get(self, name: str, version: str, **kwargs: Dict) -> Optional[FeatureSet]: :type version: str :raises ~azure.ai.ml.exceptions.ValidationException: Raised if FeatureSet cannot be successfully identified and retrieved. Details will be provided in the error message. + :raises ~azure.core.exceptions.HttpResponseError: Raised if the corresponding name and version cannot be + retrieved from the service. :return: FeatureSet asset object. :rtype: ~azure.ai.ml.entities.FeatureSet """ diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_store_operations.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_store_operations.py index e76794cce543..3a89fce0886c 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_store_operations.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_feature_store_operations.py @@ -113,11 +113,13 @@ def list(self, *, scope: str = Scope.RESOURCE_GROUP, **kwargs: Dict) -> Iterable @distributed_trace @monitor_with_activity(ops_logger, "FeatureStore.Get", ActivityType.PUBLICAPI) # pylint: disable=arguments-renamed - def get(self, name: str, **kwargs: Any) -> Optional[FeatureStore]: + def get(self, name: str, **kwargs: Any) -> FeatureStore: """Get a feature store by name. :param name: Name of the feature store. :type name: str + :raises ~azure.core.exceptions.HttpResponseError: Raised if the corresponding name and version cannot be + retrieved from the service. :return: The feature store with the provided name. :rtype: FeatureStore """ diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_registry_operations.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_registry_operations.py index c35b723883e0..7d28cebf65ca 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_registry_operations.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_registry_operations.py @@ -72,13 +72,15 @@ def list(self, *, scope: str = Scope.RESOURCE_GROUP) -> Iterable[Registry]: ) @monitor_with_activity(ops_logger, "Registry.Get", ActivityType.PUBLICAPI) - def get(self, name: Optional[str] = None) -> Optional[Registry]: + def get(self, name: Optional[str] = None) -> Registry: """Get a registry by name. :param name: Name of the registry. :type name: str :raises ~azure.ai.ml.exceptions.ValidationException: Raised if Registry name cannot be successfully validated. Details will be provided in the error message. + :raises ~azure.core.exceptions.HttpResponseError: Raised if the corresponding name and version cannot be + retrieved from the service. :return: The registry with the provided name. :rtype: ~azure.ai.ml.entities.Registry """ diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_connections_operations.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_connections_operations.py index 81356c5977e3..0910f421a912 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_connections_operations.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_connections_operations.py @@ -47,11 +47,13 @@ def __init__( self._init_kwargs = kwargs @monitor_with_activity(ops_logger, "WorkspaceConnections.Get", ActivityType.PUBLICAPI) - def get(self, name: str, **kwargs: Dict) -> Optional[WorkspaceConnection]: + def get(self, name: str, **kwargs: Dict) -> WorkspaceConnection: """Get a workspace connection by name. :param name: Name of the workspace connection. :type name: str + :raises ~azure.core.exceptions.HttpResponseError: Raised if the corresponding name and version cannot be + retrieved from the service. :return: The workspace connection with the provided name. :rtype: ~azure.ai.ml.entities.WorkspaceConnection diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_hub_operation.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_hub_operation.py index db488b876961..e374be4d0252 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_hub_operation.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_hub_operation.py @@ -92,11 +92,13 @@ def list(self, *, scope: str = Scope.RESOURCE_GROUP) -> Iterable[WorkspaceHub]: @distributed_trace @monitor_with_activity(ops_logger, "WorkspaceHub.Get", ActivityType.PUBLICAPI) # pylint: disable=arguments-renamed, arguments-differ - def get(self, name: str, **kwargs: Dict) -> Optional[WorkspaceHub]: + def get(self, name: str, **kwargs: Dict) -> WorkspaceHub: """Get a Workspace WorkspaceHub by name. :param name: Name of the WorkspaceHub. :type name: str + :raises ~azure.core.exceptions.HttpResponseError: Raised if the corresponding name and version cannot be + retrieved from the service. :return: The WorkspaceHub with the provided name. :rtype: ~azure.ai.ml.entities.WorkspaceHub From 48961be3cb4468ac018d8c0bed9844824ed2b743 Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Sun, 3 Mar 2024 18:28:03 -0800 Subject: [PATCH 2/9] Remove duplicate overloads --- .../ai/ml/entities/_inputs_outputs/input.py | 13 ---- .../ai/ml/entities/_inputs_outputs/output.py | 75 ++++++++----------- 2 files changed, 32 insertions(+), 56 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/input.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/input.py index 0ed8270c8184..16e5171663d4 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/input.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/input.py @@ -85,19 +85,6 @@ def __init__( ) -> None: """""" - @overload - def __init__( - self, - *, - type: Literal["uri_folder"] = "uri_folder", - path: Optional[str] = None, - mode: Optional[str] = None, - optional: Optional[bool] = None, - description: Optional[str] = None, - **kwargs: Any, - ) -> None: - """""" - @overload def __init__( self, diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/output.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/output.py index fc6a3691cac9..9d34f9c8589a 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/output.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_inputs_outputs/output.py @@ -34,12 +34,40 @@ def __init__( @overload def __init__( self, - type: Literal["uri_folder"] = "uri_folder", + type: Literal["uri_file"] = "uri_file", path: Optional[str] = None, mode: Optional[str] = None, description: Optional[str] = None, + ): + """Define a URI file output. + + :keyword type: The type of the data output. Can only be set to 'uri_file'. + :paramtype type: str + :keyword path: The remote path where the output should be stored. + :paramtype path: str + :keyword mode: The access mode of the data output. Accepted values are + * 'rw_mount': Read-write mount the data, + * 'upload': Upload the data from the compute target, + * 'direct': Pass in the URI as a string + :paramtype mode: str + :keyword description: The description of the output. + :paramtype description: str + :keyword name: The name to be used to register the output as a Data or Model asset. A name can be set without + setting a version. + :paramtype name: str + :keyword version: The version used to register the output as a Data or Model asset. A version can be set only + when name is set. + :paramtype version: str + """ + + def __init__( + self, + type: str = AssetTypes.URI_FOLDER, + path: Optional[str] = None, + mode: Optional[str] = None, + description: Optional[str] = None, + **kwargs: Any, ) -> None: - # pylint: disable=line-too-long """Define an output. :keyword type: The type of the data output. Accepted values are 'uri_folder', 'uri_file', 'mltable', @@ -66,9 +94,8 @@ def __init__( :paramtype early_available: bool :keyword intellectual_property: Intellectual property associated with the output. It can be an instance of `IntellectualProperty` or a dictionary that will be used to create an instance. - :paramtype intellectual_property: Union[~azure.ai.ml.entities._assets.intellectual_property.IntellectualProperty, - - dict] + :paramtype intellectual_property: Union[ + ~azure.ai.ml.entities._assets.intellectual_property.IntellectualProperty, dict] .. admonition:: Example: @@ -79,44 +106,6 @@ def __init__( :dedent: 8 :caption: Creating a CommandJob with a folder output. """ - - @overload - def __init__( - self, - type: Literal["uri_file"] = "uri_file", - path: Optional[str] = None, - mode: Optional[str] = None, - description: Optional[str] = None, - ): - """Define a URI file output. - - :keyword type: The type of the data output. Can only be set to 'uri_file'. - :paramtype type: str - :keyword path: The remote path where the output should be stored. - :paramtype path: str - :keyword mode: The access mode of the data output. Accepted values are - * 'rw_mount': Read-write mount the data, - * 'upload': Upload the data from the compute target, - * 'direct': Pass in the URI as a string - :paramtype mode: str - :keyword description: The description of the output. - :paramtype description: str - :keyword name: The name to be used to register the output as a Data or Model asset. A name can be set without - setting a version. - :paramtype name: str - :keyword version: The version used to register the output as a Data or Model asset. A version can be set only - when name is set. - :paramtype version: str - """ - - def __init__( - self, - type: str = AssetTypes.URI_FOLDER, - path: Optional[str] = None, - mode: Optional[str] = None, - description: Optional[str] = None, - **kwargs: Any, - ) -> None: super(Output, self).__init__(type=type) # As an annotation, it is not allowed to initialize the _port_name. self._port_name = None From e87555331919589174c1cb83d29e91f0dd1f6d5f Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Thu, 7 Mar 2024 08:49:16 -0800 Subject: [PATCH 3/9] Fix sphinx errors --- .../ml/entities/_job/pipeline/_attr_dict.py | 3 ++- .../_job/sweep/parameterized_sweep.py | 17 +++++++++++++---- .../ai/ml/entities/_job/sweep/sweep_job.py | 16 +++++++++++++--- .../connections/workspace_connection.py | 19 ++++++++----------- .../ai/ml/operations/_model_operations.py | 4 ++-- sdk/ml/azure-ai-ml/samples/ml_samples_misc.py | 9 +++++++++ .../ml_samples_pipeline_job_configurations.py | 1 + 7 files changed, 48 insertions(+), 21 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/pipeline/_attr_dict.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/pipeline/_attr_dict.py index ba92ac8dbaeb..194b0fa10880 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/pipeline/_attr_dict.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/pipeline/_attr_dict.py @@ -12,7 +12,7 @@ V = TypeVar("V") -class _AttrDict(Generic[K, V], dict, ABC): +class _AttrDict(Generic[K, V], Dict, ABC): """This class is used for accessing values with instance.some_key. It supports the following scenarios: 1. Setting arbitrary attribute, eg: obj.resource_layout.node_count = 2 @@ -34,6 +34,7 @@ def __init__(self, allowed_keys: Optional[Dict] = None, **kwargs: Any): :param allowed_keys: A dictionary of keys that allowed to set as arbitrary attributes. None means all keys can be set as arbitrary attributes. + :type dict :param kwargs: A dictionary of additional configuration parameters. :type kwargs: dict diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/parameterized_sweep.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/parameterized_sweep.py index 9bfab59275e3..1d61320ceb7e 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/parameterized_sweep.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/parameterized_sweep.py @@ -66,10 +66,19 @@ def __init__( :param early_termination: Early termination policy for sweep job. :type early_termination: ~azure.ai.ml.entities._job.sweep.early_termination_policy.EarlyTerminationPolicy :param search_space: Search space for sweep job. - :type search_space: Dict[str, Union[~azure.ai.ml.sweep.Choice, ~azure.ai.ml.sweep.LogNormal, - ~azure.ai.ml.sweep.LogUniform, ~azure.ai.ml.sweep.Normal, ~azure.ai.ml.sweep.QLogNormal, - ~azure.ai.ml.sweep.QLogUniform, ~azure.ai.ml.sweep.QNormal, ~azure.ai.ml.sweep.QUniform, - ~azure.ai.ml.sweep.Randint, ~azure.ai.ml.sweep.Uniform]] + :type search_space: Dict[str, Union[ + ~azure.ai.ml.sweep.Choice, + ~azure.ai.ml.sweep.LogNormal, + ~azure.ai.ml.sweep.LogUniform, + ~azure.ai.ml.sweep.Normal, + ~azure.ai.ml.sweep.QLogNormal, + ~azure.ai.ml.sweep.QLogUniform, + ~azure.ai.ml.sweep.QNormal, + ~azure.ai.ml.sweep.QUniform, + ~azure.ai.ml.sweep.Randint, + ~azure.ai.ml.sweep.Uniform + + ]] :param queue_settings: Queue settings for sweep job. :type queue_settings: ~azure.ai.ml.entities.QueueSettings :param resources: Compute Resource configuration for the job. diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py index 5adb05c1fa36..27a401c7b316 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py @@ -88,16 +88,21 @@ class SweepJob(Job, ParameterizedSweep, JobIOMixin): :paramtype identity: Union[ ~azure.ai.ml.ManagedIdentityConfiguration, ~azure.ai.ml.AmlTokenConfiguration, - ~azure.ai.ml.UserIdentityConfiguration] + ~azure.ai.ml.UserIdentityConfiguration + + ] + :keyword inputs: Inputs to the command. :paramtype inputs: dict :keyword outputs: Mapping of output data bindings used in the job. :paramtype outputs: dict[str, ~azure.ai.ml.Output] :keyword sampling_algorithm: The hyperparameter sampling algorithm to use over the `search_space`. Defaults to "random". - :paramtype sampling_algorithm: str + + :paramtype sampling_algorithm: str :keyword search_space: Dictionary of the hyperparameter search space. The key is the name of the hyperparameter and the value is the parameter expression. + :paramtype search_space: Dict :keyword objective: Metric to optimize for. :paramtype objective: Objective @@ -111,12 +116,17 @@ class SweepJob(Job, ParameterizedSweep, JobIOMixin): ~azure.ai.ml.entities.CommandComponent ] + :keyword early_termination: The early termination policy to use. A trial job is canceled when the criteria of the specified policy are met. If omitted, no early termination policy will be applied. + :paramtype early_termination: Union[ ~azure.mgmt.machinelearningservices.models.BanditPolicy, ~azure.mgmt.machinelearningservices.models.MedianStoppingPolicy, - ~azure.mgmt.machinelearningservices.models.TruncationSelectionPolicy] + ~azure.mgmt.machinelearningservices.models.TruncationSelectionPolicy + + ] + :keyword limits: Limits for the sweep job. :paramtype limits: ~azure.ai.ml.entities.SweepJobLimits :keyword queue_settings: Queue settings for the job. diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_workspace/connections/workspace_connection.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_workspace/connections/workspace_connection.py index 5469f85d5acb..4aa84ecdc689 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_workspace/connections/workspace_connection.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_workspace/connections/workspace_connection.py @@ -4,35 +4,31 @@ # pylint: disable=protected-access +import warnings from os import PathLike from pathlib import Path -import warnings from typing import IO, Any, AnyStr, Dict, List, Optional, Type, Union, cast +from azure.ai.ml._restclient.v2023_08_01_preview.models import ( + WorkspaceConnectionPropertiesV2BasicResource as RestWorkspaceConnection, +) from azure.ai.ml._restclient.v2024_01_01_preview.models import ( ConnectionCategory, NoneAuthTypeWorkspaceConnectionProperties, ) -from azure.ai.ml._restclient.v2023_08_01_preview.models import ( - WorkspaceConnectionPropertiesV2BasicResource as RestWorkspaceConnection, -) from azure.ai.ml._schema.workspace.connections.workspace_connection import WorkspaceConnectionSchema from azure.ai.ml._utils._experimental import experimental from azure.ai.ml._utils.utils import _snake_to_camel, camel_to_snake, dump_yaml_to_file -from azure.ai.ml.constants._common import ( - BASE_PATH_CONTEXT_KEY, - PARAMS_OVERRIDE_KEY, - WorkspaceConnectionTypes, -) +from azure.ai.ml.constants._common import BASE_PATH_CONTEXT_KEY, PARAMS_OVERRIDE_KEY, WorkspaceConnectionTypes from azure.ai.ml.entities._credentials import ( AccessKeyConfiguration, ApiKeyConfiguration, ManagedIdentityConfiguration, + NoneCredentialConfiguration, PatTokenConfiguration, SasTokenConfiguration, ServicePrincipalConfiguration, UsernamePasswordConfiguration, - NoneCredentialConfiguration, _BaseIdentityConfiguration, ) from azure.ai.ml.entities._resource import Resource @@ -174,6 +170,7 @@ def credentials( ~azure.ai.ml.entities.ServicePrincipalConfiguration, ~azure.ai.ml.entities.AccessKeyConfiguration, ~azure.ai.ml.entities.ApiKeyConfiguration + ] """ return self._credentials @@ -373,8 +370,8 @@ def _get_entity_class_from_type(cls, conn_type: Optional[str]) -> Type: from .workspace_connection_subtypes import ( AzureAISearchWorkspaceConnection, AzureAIServiceWorkspaceConnection, - AzureOpenAIWorkspaceConnection, AzureBlobStoreWorkspaceConnection, + AzureOpenAIWorkspaceConnection, ) # Connection categories don't perfectly follow perfect camel casing, so lower diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_model_operations.py b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_model_operations.py index 4c7d91775ebe..52790a2e6a2f 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_model_operations.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/operations/_model_operations.py @@ -415,7 +415,7 @@ def archive( :end-before: [END model_operations_archive] :language: python :dedent: 8 - :caption: Archive a model example. + :caption: Archive a model. """ _archive_or_restore( asset_operations=self, @@ -451,7 +451,7 @@ def restore( :end-before: [END model_operations_restore] :language: python :dedent: 8 - :caption: Restore a model example. + :caption: Restore an archived model. """ _archive_or_restore( asset_operations=self, diff --git a/sdk/ml/azure-ai-ml/samples/ml_samples_misc.py b/sdk/ml/azure-ai-ml/samples/ml_samples_misc.py index 4dcd80c0b42b..10dffcc9f168 100644 --- a/sdk/ml/azure-ai-ml/samples/ml_samples_misc.py +++ b/sdk/ml/azure-ai-ml/samples/ml_samples_misc.py @@ -111,8 +111,17 @@ def ml_misc_config_0(self): }, stage="Production", ) + ml_client.models.create_or_update(model) # [END model_entity_create] + # [START model_operations_archive] + ml_client.models.archive(name="model1", version="5") + # [END model_operations_archive] + + # [START model_operations_restore] + ml_client.models.restore(name="model1", version="5") + # [END model_operations_restore] + # [START model_batch_deployment_settings_entity_create] from azure.ai.ml.entities._deployment.model_batch_deployment_settings import ModelBatchDeploymentSettings diff --git a/sdk/ml/azure-ai-ml/samples/ml_samples_pipeline_job_configurations.py b/sdk/ml/azure-ai-ml/samples/ml_samples_pipeline_job_configurations.py index 284dafe6da2f..e9d7a03c9a18 100644 --- a/sdk/ml/azure-ai-ml/samples/ml_samples_pipeline_job_configurations.py +++ b/sdk/ml/azure-ai-ml/samples/ml_samples_pipeline_job_configurations.py @@ -83,6 +83,7 @@ def sample_pipeline_func(pipeline_input1, pipeline_input2): settings=PipelineJobSettings(force_rerun=True, default_compute="cpu-cluster"), jobs={"component1": component_func(component_in_number=1.0, component_in_path=uri_file_input)}, ) + ml_client.jobs.create_or_update(pipeline_job) # [END configure_pipeline_job_and_settings] From 02bf12e66cc3afba022de50d913fcb9d189a0dcc Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Thu, 7 Mar 2024 08:59:16 -0800 Subject: [PATCH 4/9] Fix indentation --- sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py index 27a401c7b316..424a23b316a7 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/sweep_job.py @@ -99,7 +99,7 @@ class SweepJob(Job, ParameterizedSweep, JobIOMixin): :keyword sampling_algorithm: The hyperparameter sampling algorithm to use over the `search_space`. Defaults to "random". - :paramtype sampling_algorithm: str + :paramtype sampling_algorithm: str :keyword search_space: Dictionary of the hyperparameter search space. The key is the name of the hyperparameter and the value is the parameter expression. From ab0538d749bc3b2fabb140f63bff504648d5fc5a Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Thu, 7 Mar 2024 09:11:09 -0800 Subject: [PATCH 5/9] Turn on strict sphinx check --- sdk/ml/azure-ai-ml/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/ml/azure-ai-ml/pyproject.toml b/sdk/ml/azure-ai-ml/pyproject.toml index f3d3c2c92ab7..132dbd1928d1 100644 --- a/sdk/ml/azure-ai-ml/pyproject.toml +++ b/sdk/ml/azure-ai-ml/pyproject.toml @@ -4,7 +4,7 @@ pyright = false type_check_samples = false verifytypes = false pylint = true -strict_sphinx = false +strict_sphinx = true [tool.isort] From 51d141ac4efda09831f0e5aa21d87738c9287265 Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Fri, 8 Mar 2024 12:55:34 -0800 Subject: [PATCH 6/9] Implicitly expose search_space and _credentials classes to avoid duplicate object exposures --- sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py | 32 +++++++- .../azure/ai/ml/entities/__init__.py | 79 +++++++++++++------ .../ai/ml/entities/_job/sweep/search_space.py | 1 - 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py index e15a64da3329..e249b3be88aa 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py @@ -5,6 +5,7 @@ __path__ = __import__("pkgutil").extend_path(__path__, __name__) import logging +from typing import Any, List, Optional # from .entities._builders.parallel_func import parallel from azure.ai.ml.entities._inputs_outputs import Input, Output @@ -14,7 +15,6 @@ from ._version import VERSION from .entities._builders.command_func import command from .entities._builders.spark_func import spark -from .entities._credentials import AmlTokenConfiguration, ManagedIdentityConfiguration, UserIdentityConfiguration from .entities._job.distribution import MpiDistribution, PyTorchDistribution, RayDistribution, TensorFlowDistribution from .entities._load_functions import ( load_batch_deployment, @@ -52,9 +52,6 @@ "PyTorchDistribution", "TensorFlowDistribution", "RayDistribution", - "ManagedIdentityConfiguration", - "AmlTokenConfiguration", - "UserIdentityConfiguration", "load_batch_deployment", "load_batch_endpoint", "load_component", @@ -77,3 +74,30 @@ ] __version__ = VERSION + + +def __dir__() -> List[str]: + return __all__ + + +# Allow importing these types for backwards compatibility + + +def __getattr__(name: str): + requested: Optional[Any] = None + if name == "AmlTokenConfiguration": + from .entities._credentials import AmlTokenConfiguration + + requested = AmlTokenConfiguration + if name == "ManagedIdentityConfiguration": + from .entities._credentials import ManagedIdentityConfiguration + + requested = ManagedIdentityConfiguration + if name == "UserIdentityConfiguration": + from .entities._credentials import UserIdentityConfiguration + + requested = UserIdentityConfiguration + + if requested: + return requested + raise AttributeError(f"module 'azure.ai.ml.entities' has no attribute {name}") diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py index efc3858e166d..197e1b5a6256 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py @@ -9,6 +9,8 @@ # pylint: disable=naming-mismatch __path__ = __import__("pkgutil").extend_path(__path__, __name__) +from typing import Any, List, Optional + from azure.ai.ml._restclient.v2022_10_01.models import CreatedByType from azure.ai.ml._restclient.v2022_10_01_preview.models import UsageUnit @@ -138,18 +140,6 @@ from ._job.spark_job import SparkJob from ._job.spark_job_entry import SparkJobEntry, SparkJobEntryType from ._job.spark_resource_configuration import SparkResourceConfiguration -from ._job.sweep.search_space import ( - Choice, - LogNormal, - LogUniform, - Normal, - QLogNormal, - QLogUniform, - QNormal, - QUniform, - Randint, - Uniform, -) from ._monitoring.alert_notification import AlertNotification from ._monitoring.compute import ServerlessSparkCompute from ._monitoring.definition import MonitorDefinition @@ -325,16 +315,6 @@ "ParallelComponent", "CommandComponent", "SparkComponent", - "Choice", - "Normal", - "LogNormal", - "QNormal", - "QLogNormal", - "Randint", - "Uniform", - "QUniform", - "LogUniform", - "QLogUniform", "ResourceRequirementsSettings", "ResourceSettings", "AssignedUserConfiguration", @@ -472,3 +452,58 @@ "RequestLogging", "NoneCredentialConfiguration", ] + + +def __dir__() -> List[str]: + return __all__ + + +# Allow importing these types for backwards compatibility + + +def __getattr__(name: str): + requested: Optional[Any] = None + if name == "Choice": + from ._job.sweep.search_space import Choice + + requested = Choice + if name == "LogNormal": + from ._job.sweep.search_space import LogNormal + + requested = LogNormal + if name == "LogUniform": + from ._job.sweep.search_space import LogUniform + + requested = LogUniform + if name == "Normal": + from ._job.sweep.search_space import Normal + + requested = Normal + if name == "QLogNormal": + from ._job.sweep.search_space import QLogNormal + + requested = QLogNormal + if name == "QLogUniform": + from ._job.sweep.search_space import QLogUniform + + requested = QLogUniform + if name == "QNormal": + from ._job.sweep.search_space import QNormal + + requested = QNormal + if name == "QUniform": + from ._job.sweep.search_space import QUniform + + requested = QUniform + if name == "Randint": + from ._job.sweep.search_space import Randint + + requested = Randint + if name == "Uniform": + from ._job.sweep.search_space import Uniform + + requested = Uniform + + if requested: + return requested + raise AttributeError(f"module 'azure.ai.ml.entities' has no attribute {name}") diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/search_space.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/search_space.py index 0df06d9539ea..90d02b89a462 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/search_space.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/sweep/search_space.py @@ -267,7 +267,6 @@ def _from_rest_object(cls, obj: List) -> "Randint": class Uniform(SweepDistribution): """ - :noindex: Uniform distribution configuration. From 2998115fd99de38322ca06752e6a2a80c731c328 Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Fri, 8 Mar 2024 14:46:01 -0800 Subject: [PATCH 7/9] Add deprecation warning message for imports and update CHANGELOG --- sdk/ml/azure-ai-ml/CHANGELOG.md | 16 ++++++++ sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py | 17 ++++++--- .../azure/ai/ml/entities/__init__.py | 37 +++++++++++-------- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/sdk/ml/azure-ai-ml/CHANGELOG.md b/sdk/ml/azure-ai-ml/CHANGELOG.md index fd3bd4ee19d8..a08a219c68e5 100644 --- a/sdk/ml/azure-ai-ml/CHANGELOG.md +++ b/sdk/ml/azure-ai-ml/CHANGELOG.md @@ -10,6 +10,22 @@ ### Other Changes +- The following classes will still be able to be imported from azure.ai.ml, but the import is deprecated and emits a warning. Instead, please import them from azure.ai.ml.entities. + - AmlTokenConfiguration + - ManagedIdentityConfiguration + - UserIdentityConfiguration +- The following classes will still be able to be imported from azure.ai.ml.entities, but the import is deprecated and emits a warning. Instead, please import them from azure.ai.ml.sweep. + - Choice + - Uniform + - LogUniform + - QLogUniform + - QUniform + - QLogNormal + - QNormal + - LogNormal + - Normal + - Randint + ## 1.14.0 (unreleased) ### Features Added diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py index e249b3be88aa..66172807c583 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py @@ -5,7 +5,7 @@ __path__ = __import__("pkgutil").extend_path(__path__, __name__) import logging -from typing import Any, List, Optional +from typing import Any, Optional # from .entities._builders.parallel_func import parallel from azure.ai.ml.entities._inputs_outputs import Input, Output @@ -76,15 +76,12 @@ __version__ = VERSION -def __dir__() -> List[str]: - return __all__ - - # Allow importing these types for backwards compatibility def __getattr__(name: str): requested: Optional[Any] = None + if name == "AmlTokenConfiguration": from .entities._credentials import AmlTokenConfiguration @@ -99,5 +96,13 @@ def __getattr__(name: str): requested = UserIdentityConfiguration if requested: + if not getattr(__getattr__, "warning_issued", False): + logging.warning( + " %s will be removed from the azure.ai.ml namespace in a future release." + " Please use the azure.ai.ml.entities namespace instead.", + name, + ) + __getattr__.warning_issued = True return requested - raise AttributeError(f"module 'azure.ai.ml.entities' has no attribute {name}") + + raise AttributeError(f"module 'azure.ai.ml' has no attribute {name}") diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py index 197e1b5a6256..e0b67e2b7263 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py @@ -9,7 +9,8 @@ # pylint: disable=naming-mismatch __path__ = __import__("pkgutil").extend_path(__path__, __name__) -from typing import Any, List, Optional +import logging +from typing import Any, Optional from azure.ai.ml._restclient.v2022_10_01.models import CreatedByType from azure.ai.ml._restclient.v2022_10_01_preview.models import UsageUnit @@ -453,57 +454,61 @@ "NoneCredentialConfiguration", ] - -def __dir__() -> List[str]: - return __all__ - - # Allow importing these types for backwards compatibility def __getattr__(name: str): requested: Optional[Any] = None + if name == "Choice": - from ._job.sweep.search_space import Choice + from ..sweep import Choice requested = Choice if name == "LogNormal": - from ._job.sweep.search_space import LogNormal + from ..sweep import LogNormal requested = LogNormal if name == "LogUniform": - from ._job.sweep.search_space import LogUniform + from ..sweep import LogUniform requested = LogUniform if name == "Normal": - from ._job.sweep.search_space import Normal + from ..sweep import Normal requested = Normal if name == "QLogNormal": - from ._job.sweep.search_space import QLogNormal + from ..sweep import QLogNormal requested = QLogNormal if name == "QLogUniform": - from ._job.sweep.search_space import QLogUniform + from ..sweep import QLogUniform requested = QLogUniform if name == "QNormal": - from ._job.sweep.search_space import QNormal + from ..sweep import QNormal requested = QNormal if name == "QUniform": - from ._job.sweep.search_space import QUniform + from ..sweep import QUniform requested = QUniform if name == "Randint": - from ._job.sweep.search_space import Randint + from ..sweep import Randint requested = Randint if name == "Uniform": - from ._job.sweep.search_space import Uniform + from ..sweep import Uniform requested = Uniform if requested: + if not getattr(__getattr__, "warning_issued", False): + logging.warning( + " %s will be removed from the azure.ai.ml.entities namespace in a future release." + " Please import from the azure.ai.ml.sweep namespace instead.", + name, + ) + __getattr__.warning_issued = True return requested + raise AttributeError(f"module 'azure.ai.ml.entities' has no attribute {name}") From 28645106aea3758eb8a6b4fda5448ad37bd059f4 Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Fri, 8 Mar 2024 14:58:26 -0800 Subject: [PATCH 8/9] Update formatting --- sdk/ml/azure-ai-ml/CHANGELOG.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sdk/ml/azure-ai-ml/CHANGELOG.md b/sdk/ml/azure-ai-ml/CHANGELOG.md index a08a219c68e5..ab7206b5bd26 100644 --- a/sdk/ml/azure-ai-ml/CHANGELOG.md +++ b/sdk/ml/azure-ai-ml/CHANGELOG.md @@ -10,21 +10,21 @@ ### Other Changes -- The following classes will still be able to be imported from azure.ai.ml, but the import is deprecated and emits a warning. Instead, please import them from azure.ai.ml.entities. - - AmlTokenConfiguration - - ManagedIdentityConfiguration - - UserIdentityConfiguration -- The following classes will still be able to be imported from azure.ai.ml.entities, but the import is deprecated and emits a warning. Instead, please import them from azure.ai.ml.sweep. - - Choice - - Uniform - - LogUniform - - QLogUniform - - QUniform - - QLogNormal - - QNormal - - LogNormal - - Normal - - Randint +- The following classes will still be able to be imported from `azure.ai.ml`, but the import is deprecated and emits a warning. Instead, please import them from `azure.ai.ml.entities`. + - `AmlTokenConfiguration` + - `ManagedIdentityConfiguration` + - `UserIdentityConfiguration` +- The following classes will still be able to be imported from `azure.ai.ml.entities`, but the import is deprecated and emits a warning. Instead, please import them from `azure.ai.ml.sweep`. + - `Choice` + - `Uniform` + - `LogUniform` + - `QLogUniform` + - `QUniform` + - `QLogNormal` + - `QNormal` + - `LogNormal` + - `Normal` + - `Randint` ## 1.14.0 (unreleased) From 5caaba766ed909e6e81abccf71b46b7647552194 Mon Sep 17 00:00:00 2001 From: Diondra Peck Date: Fri, 8 Mar 2024 16:18:27 -0800 Subject: [PATCH 9/9] Ignore mypy error --- sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py | 2 +- sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py index 66172807c583..e50df9de99c3 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/__init__.py @@ -102,7 +102,7 @@ def __getattr__(name: str): " Please use the azure.ai.ml.entities namespace instead.", name, ) - __getattr__.warning_issued = True + __getattr__.warning_issued = True # type: ignore[attr-defined] return requested raise AttributeError(f"module 'azure.ai.ml' has no attribute {name}") diff --git a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py index e0b67e2b7263..75c08c62d535 100644 --- a/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py +++ b/sdk/ml/azure-ai-ml/azure/ai/ml/entities/__init__.py @@ -508,7 +508,7 @@ def __getattr__(name: str): " Please import from the azure.ai.ml.sweep namespace instead.", name, ) - __getattr__.warning_issued = True + __getattr__.warning_issued = True # type: ignore[attr-defined] return requested raise AttributeError(f"module 'azure.ai.ml.entities' has no attribute {name}")