Skip to content

Commit 0b9ec60

Browse files
added adlfs user agent
1 parent 38c3932 commit 0b9ec60

File tree

2 files changed

+118
-18
lines changed

2 files changed

+118
-18
lines changed

adlfs/spec.py

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
get_blob_metadata,
4646
match_blob_version,
4747
)
48+
from ._version import version as __version__
4849

4950
logger = logging.getLogger(__name__)
5051

@@ -71,6 +72,7 @@
7172
_DEFAULT_BLOCK_SIZE = 4 * 1024 * 1024
7273

7374
_SOCKET_TIMEOUT_DEFAULT = object()
75+
_USER_AGENT = f"adlfs/{__version__}"
7476

7577

7678
# https://github.com/Azure/azure-sdk-for-python/issues/11419#issuecomment-628143480
@@ -118,6 +120,35 @@ def _coalesce_version_id(*args) -> Optional[str]:
118120
return version_ids.pop()
119121

120122

123+
def _create_aio_blob_service_client(account_url: str, location_mode: Optional[str] = None, credential: Optional[str] = None) -> AIOBlobServiceClient:
124+
if credential is not None:
125+
return AIOBlobServiceClient(
126+
account_url=account_url,
127+
credential=credential,
128+
_location_mode=location_mode,
129+
user_agent=_USER_AGENT,
130+
)
131+
elif location_mode is not None:
132+
return AIOBlobServiceClient(
133+
account_url=account_url,
134+
credential=None,
135+
_location_mode=location_mode,
136+
user_agent=_USER_AGENT,
137+
)
138+
else:
139+
return AIOBlobServiceClient(
140+
account_url=account_url,
141+
user_agent=_USER_AGENT,
142+
)
143+
144+
145+
def _create_aio_blob_service_client_from_connection_string(connection_string: str) -> AIOBlobServiceClient:
146+
return AIOBlobServiceClient.from_connection_string(
147+
conn_str=connection_string,
148+
user_agent=_USER_AGENT,
149+
)
150+
151+
121152
class AzureBlobFileSystem(AsyncFileSystem):
122153
"""
123154
Access Azure Datalake Gen2 and Azure Storage if it were a file system using Multiprotocol Access
@@ -473,8 +504,8 @@ def do_connect(self):
473504

474505
try:
475506
if self.connection_string is not None:
476-
self.service_client = AIOBlobServiceClient.from_connection_string(
477-
conn_str=self.connection_string
507+
self.service_client = _create_aio_blob_service_client_from_connection_string(
508+
connection_string=self.connection_string,
478509
)
479510
elif self.account_name is not None:
480511
if hasattr(self, "account_host"):
@@ -487,26 +518,25 @@ def do_connect(self):
487518
creds = [self.credential, self.account_key]
488519
if any(creds):
489520
self.service_client = [
490-
AIOBlobServiceClient(
521+
_create_aio_blob_service_client(
491522
account_url=self.account_url,
523+
location_mode=self.location_mode,
492524
credential=cred,
493-
_location_mode=self.location_mode,
494525
)
495526
for cred in creds
496527
if cred is not None
497528
][0]
498529
elif self.sas_token is not None:
499530
if not self.sas_token.startswith("?"):
500531
self.sas_token = f"?{self.sas_token}"
501-
self.service_client = AIOBlobServiceClient(
532+
self.service_client = _create_aio_blob_service_client(
502533
account_url=self.account_url + self.sas_token,
503-
credential=None,
504-
_location_mode=self.location_mode,
534+
location_mode=self.location_mode,
505535
)
506536
else:
507537
# Fall back to anonymous login, and assume public container
508-
self.service_client = AIOBlobServiceClient(
509-
account_url=self.account_url
538+
self.service_client = _create_aio_blob_service_client(
539+
account_url=self.account_url,
510540
)
511541
else:
512542
raise ValueError(
@@ -1950,6 +1980,7 @@ def __init__(
19501980
self.end = None
19511981
self.start = None
19521982
self.closed = False
1983+
self._user_agent = f"adlfs/{__version__}"
19531984

19541985
if cache_options is None:
19551986
cache_options = {}
@@ -2045,29 +2076,33 @@ def connect_client(self):
20452076
)
20462077

20472078
creds = [self.fs.sync_credential, self.fs.account_key, self.fs.credential]
2079+
print(f"creds: {creds}")
20482080
if any(creds):
2081+
print("call")
20492082
self.container_client = [
2050-
AIOBlobServiceClient(
2083+
_create_aio_blob_service_client(
20512084
account_url=self.fs.account_url,
20522085
credential=cred,
2053-
_location_mode=self.fs.location_mode,
2086+
location_mode=self.fs.location_mode,
20542087
).get_container_client(self.container_name)
20552088
for cred in creds
20562089
if cred is not None
20572090
][0]
20582091
elif self.fs.connection_string is not None:
2059-
self.container_client = AIOBlobServiceClient.from_connection_string(
2060-
conn_str=self.fs.connection_string
2092+
print("call")
2093+
self.container_client = _create_aio_blob_service_client_from_connection_string(
2094+
connection_string=self.fs.connection_string,
20612095
).get_container_client(self.container_name)
20622096
elif self.fs.sas_token is not None:
2063-
self.container_client = AIOBlobServiceClient(
2064-
account_url=self.fs.account_url + self.fs.sas_token, credential=None
2097+
print("call")
2098+
self.container_client = _create_aio_blob_service_client(
2099+
account_url=self.fs.account_url + self.fs.sas_token,
20652100
).get_container_client(self.container_name)
20662101
else:
2067-
self.container_client = AIOBlobServiceClient(
2068-
account_url=self.fs.account_url
2102+
print("call")
2103+
self.container_client = _create_aio_blob_service_client(
2104+
account_url=self.fs.account_url,
20692105
).get_container_client(self.container_name)
2070-
20712106
except Exception as e:
20722107
raise ValueError(
20732108
f"Unable to fetch container_client with provided params for {e}!!"

adlfs/tests/test_spec.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
from pandas.testing import assert_frame_equal
1414

1515
from adlfs import AzureBlobFile, AzureBlobFileSystem
16+
from adlfs._version import version as __version__
17+
from azure.storage.blob.aio import BlobServiceClient as AIOBlobServiceClient
18+
import asyncio
19+
1620

1721
URL = "http://127.0.0.1:10000"
1822
ACCOUNT_NAME = "devstoreaccount1"
@@ -2045,3 +2049,64 @@ def test_open_file_x(storage: azure.storage.blob.BlobServiceClient, tmpdir):
20452049
with fs.open("data/afile", "xb") as f:
20462050
pass
20472051
assert fs.cat_file("data/afile") == b"data"
2052+
2053+
2054+
def test_user_agent_connection_str(storage: azure.storage.blob.BlobServiceClient, mocker):
2055+
fs = AzureBlobFileSystem(
2056+
account_name=storage.account_name, connection_string=CONN_STR
2057+
)
2058+
mock_client = mocker.patch.object(AIOBlobServiceClient, "from_connection_string", return_value=mocker.AsyncMock())
2059+
2060+
fs.do_connect()
2061+
mock_client.assert_called_once()
2062+
assert "user_agent" in mock_client.call_args.kwargs
2063+
assert mock_client.call_args.kwargs["user_agent"] == f"adlfs/{__version__}"
2064+
2065+
2066+
def test_user_agent_initializer(storage: azure.storage.blob.BlobServiceClient, mocker):
2067+
fs = AzureBlobFileSystem(
2068+
account_name=storage.account_name,
2069+
)
2070+
mock_client = mocker.patch("adlfs.spec.AIOBlobServiceClient", spec=True)
2071+
2072+
fs.do_connect()
2073+
mock_client.assert_called_once()
2074+
assert "user_agent" in mock_client.call_args.kwargs
2075+
assert mock_client.call_args.kwargs["user_agent"] == f"adlfs/{__version__}"
2076+
2077+
2078+
def test_user_agent_blob_file_connection_str(storage: azure.storage.blob.BlobServiceClient, mocker):
2079+
fs = AzureBlobFileSystem(
2080+
account_name=storage.account_name, connection_string=CONN_STR
2081+
)
2082+
mock_client = mocker.patch.object(AIOBlobServiceClient, "from_connection_string", return_value=mocker.AsyncMock())
2083+
mock_client.return_value.get_container_client = mocker.MagicMock()
2084+
2085+
f = AzureBlobFile(fs, "data/root/a/file.txt", mode="rb")
2086+
f.container_name = "data"
2087+
f.connect_client()
2088+
2089+
mock_client.assert_called_once()
2090+
assert "user_agent" in mock_client.call_args.kwargs
2091+
assert mock_client.call_args.kwargs["user_agent"] == f"adlfs/{__version__}"
2092+
2093+
2094+
def test_user_agent_blob_file_initializer(storage: azure.storage.blob.BlobServiceClient, mocker):
2095+
mock_client = mocker.patch("adlfs.spec.AIOBlobServiceClient", spec= True)
2096+
mock_container_client = mocker.MagicMock()
2097+
mock_blob_client = mocker.MagicMock()
2098+
mock_blob_client.__aenter__ = mocker.AsyncMock(return_value=mock_blob_client)
2099+
mock_blob_client.__aexit__ = mocker.AsyncMock()
2100+
mock_blob_client.get_blob_properties = mocker.AsyncMock(return_value={})
2101+
mock_container_client.get_blob_client = mocker.MagicMock(return_value=mock_blob_client)
2102+
mock_client.return_value.get_container_client = mocker.MagicMock(return_value=mock_container_client)
2103+
2104+
fs = AzureBlobFileSystem(
2105+
account_name=storage.account_name,
2106+
)
2107+
f = AzureBlobFile(fs, "data/root/a/file.txt", mode="rb")
2108+
f.container_name = "data"
2109+
2110+
mock_client.assert_called_once()
2111+
assert "user_agent" in mock_client.call_args.kwargs
2112+
assert mock_client.call_args.kwargs["user_agent"] == f"adlfs/{__version__}"

0 commit comments

Comments
 (0)