Skip to content
47 changes: 33 additions & 14 deletions adlfs/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from glob import has_magic

from azure.core.exceptions import (
ClientAuthenticationError,
HttpResponseError,
ResourceExistsError,
ResourceNotFoundError,
Expand All @@ -32,6 +31,7 @@

from .utils import (
close_container_client,
close_credential,
close_service_client,
filter_blobs,
get_blob_metadata,
Expand Down Expand Up @@ -449,8 +449,23 @@ def __init__(
) = self._get_credential_from_service_principal()
else:
self.sync_credential = None

# Solving issue in https://github.com/fsspec/adlfs/issues/270
if (
self.credential is None
and self.anon is False
and self.sas_token is None
and self.account_key is None
):

(
self.credential,
self.sync_credential,
) = self._get_default_azure_credential(**kwargs)

self.do_connect()
weakref.finalize(self, sync, self.loop, close_service_client, self)
weakref.finalize(self, sync, self.loop, close_credential, self)

@classmethod
def _strip_protocol(cls, path: str):
Expand Down Expand Up @@ -517,18 +532,24 @@ def _get_credential_from_service_principal(self):
return (async_credential, sync_credential)

def _get_default_azure_credential(self, **kwargs):
try:
from azure.identity.aio import (
DefaultAzureCredential as AIODefaultAzureCredential,
)

asyncio.get_child_watcher().attach_loop(self.loop)
self.credential = AIODefaultAzureCredential()
self.do_connect()
except: # noqa: E722
raise ClientAuthenticationError(
"No explict credentials provided. Failed with DefaultAzureCredential!"
)
"""
Create a Credential for authentication using DefaultAzureCredential

Returns
-------
Tuple of (Async Credential, Sync Credential).
"""

from azure.identity import DefaultAzureCredential
from azure.identity.aio import (
DefaultAzureCredential as AIODefaultAzureCredential,
)

async_credential = AIODefaultAzureCredential(**kwargs)
sync_credential = DefaultAzureCredential(**kwargs)

return (async_credential, sync_credential)

def do_connect(self):
"""Connect to the BlobServiceClient, using user-specified connection details.
Expand Down Expand Up @@ -567,8 +588,6 @@ def do_connect(self):
credential=None,
_location_mode=self.location_mode,
)
elif self.anon is False:
self._get_default_azure_credential()
else:
# Fall back to anonymous login, and assume public container
self.service_client = AIOBlobServiceClient(
Expand Down
8 changes: 8 additions & 0 deletions adlfs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ async def close_container_client(file_obj):
AzureBlobFile objects
"""
await file_obj.container_client.close()


async def close_credential(file_obj):
"""
Implements asynchronous closure of credentials for
AzureBlobFile objects
"""
await file_obj.credential.close()