Skip to content

Commit c694e3f

Browse files
authored
Gen2download failure (Azure#38986)
1 parent b52b61c commit c694e3f

File tree

3 files changed

+86
-4
lines changed

3 files changed

+86
-4
lines changed

sdk/ml/azure-ai-ml/azure/ai/ml/_artifacts/_gen2_storage_helper.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,19 @@
3636

3737
class Gen2StorageClient:
3838
def __init__(self, credential: str, file_system: str, account_url: str):
39-
service_client = DataLakeServiceClient(account_url=account_url, credential=credential)
4039
self.account_name = account_url.split(".")[0].split("//")[1]
4140
self.file_system = file_system
42-
self.file_system_client = service_client.get_file_system_client(file_system=file_system)
41+
42+
try:
43+
service_client = DataLakeServiceClient(account_url=account_url, credential=credential)
44+
self.file_system_client = service_client.get_file_system_client(file_system=file_system)
45+
except ValueError as e:
46+
api_version = e.args[0].split("\n")[-1]
47+
service_client = DataLakeServiceClient(
48+
account_url=account_url, credential=credential, api_version=api_version
49+
)
50+
self.file_system_client = service_client.get_file_system_client(file_system=file_system)
51+
4352
try:
4453
self.file_system_client.create_file_system()
4554
except ResourceExistsError:

sdk/ml/azure-ai-ml/azure/ai/ml/operations/_model_operations.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from azure.ai.ml._utils._storage_utils import get_ds_name_and_path_prefix, get_storage_client
5353
from azure.ai.ml._utils.utils import _is_evaluator, resolve_short_datastore_url, validate_ml_flow_folder
5454
from azure.ai.ml.constants._common import ARM_ID_PREFIX, ASSET_ID_FORMAT, REGISTRY_URI_FORMAT, AzureMLResourceType
55+
from azure.ai.ml.entities import AzureDataLakeGen2Datastore
5556
from azure.ai.ml.entities._assets import Environment, Model, ModelPackage
5657
from azure.ai.ml.entities._assets._artifacts.code import Code
5758
from azure.ai.ml.entities._assets.workspace_asset_reference import WorkspaceAssetReference
@@ -415,9 +416,24 @@ def download(self, name: str, version: str, download_path: Union[PathLike, str]
415416
else:
416417
raise e
417418

418-
container = ds.container_name
419-
datastore_type = ds.type
419+
if isinstance(ds, AzureDataLakeGen2Datastore):
420+
container = ds.filesystem
421+
try:
422+
from azure.identity import ClientSecretCredential
423+
424+
token_credential = ClientSecretCredential(
425+
tenant_id=ds.credentials["tenant_id"],
426+
client_id=ds.credentials["client_id"],
427+
client_secret=ds.credentials["client_secret"],
428+
authority=ds.credentials["authority_url"],
429+
)
430+
credential = token_credential
431+
except (KeyError, TypeError):
432+
pass
420433

434+
else:
435+
container = ds.container_name
436+
datastore_type = ds.type
421437
storage_client = get_storage_client(
422438
credential=credential,
423439
container_name=container,

sdk/ml/azure-ai-ml/tests/model/unittests/test_model_operations.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,63 @@ def test_restore_container(self, mock_model_operation: ModelOperations) -> None:
235235
resource_group_name=mock_model_operation._resource_group_name,
236236
)
237237

238+
def test_download_from_gen2_with_none_cred(self, mock_model_operation: ModelOperations) -> None:
239+
name = "random_string"
240+
version = "1"
241+
model = Model(
242+
name=name,
243+
version=version,
244+
path="azureml://subscriptions/subscription_id/resourcegroups/rg-name/workspaces/gen2test/datastores/adls_gen2/paths/gen2test/",
245+
)
246+
from azure.ai.ml.entities import AzureDataLakeGen2Datastore
247+
248+
datastore = AzureDataLakeGen2Datastore(name="gen2_datastore", account_name="gen2_account", filesystem="gen2")
249+
storage_client = Mock()
250+
with patch(
251+
"azure.ai.ml.operations._model_operations.get_storage_client", return_value=storage_client
252+
) as get_client_mock, patch(
253+
"azure.ai.ml.operations._model_operations.Model._from_rest_object",
254+
return_value=model,
255+
), patch(
256+
"azure.ai.ml.operations._model_operations.DatastoreOperations.get", return_value=datastore
257+
):
258+
mock_model_operation.download(name=name, version=version)
259+
get_client_mock.assert_called_once()
260+
261+
def test_download_from_gen2_with_sp_cred(self, mock_model_operation: ModelOperations) -> None:
262+
name = "random_string"
263+
version = "1"
264+
model = Model(
265+
name=name,
266+
version=version,
267+
path="azureml://subscriptions/subscription_id/resourcegroups/rg-name/workspaces/gen2test/datastores/adls_gen2/paths/gen2test/",
268+
)
269+
from azure.ai.ml.entities import AzureDataLakeGen2Datastore
270+
from azure.ai.ml.entities._credentials import ServicePrincipalConfiguration
271+
272+
datastore = AzureDataLakeGen2Datastore(
273+
name="adls_gen2_example",
274+
description="Datastore pointing to an Azure Data Lake Storage Gen2.",
275+
account_name="mytestdatalakegen2",
276+
filesystem="my-gen2-container",
277+
credentials=ServicePrincipalConfiguration(
278+
tenant_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
279+
client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
280+
client_secret="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
281+
),
282+
)
283+
storage_client = Mock()
284+
with patch(
285+
"azure.ai.ml.operations._model_operations.get_storage_client", return_value=storage_client
286+
) as get_client_mock, patch(
287+
"azure.ai.ml.operations._model_operations.Model._from_rest_object",
288+
return_value=model,
289+
), patch(
290+
"azure.ai.ml.operations._model_operations.DatastoreOperations.get", return_value=datastore
291+
):
292+
mock_model_operation.download(name=name, version=version)
293+
get_client_mock.assert_called_once()
294+
238295
def test_create_with_datastore(
239296
self,
240297
mock_workspace_scope: OperationScope,

0 commit comments

Comments
 (0)