Skip to content

Commit 1e540de

Browse files
authored
Fix typing contract for max_concurrency in File Share client (#45637)
1 parent fa44dea commit 1e540de

11 files changed

Lines changed: 127 additions & 23 deletions

File tree

sdk/storage/azure-storage-file-share/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/storage/azure-storage-file-share",
5-
"Tag": "python/storage/azure-storage-file-share_c5fe7fb7b7"
5+
"Tag": "python/storage/azure-storage-file-share_1fb2aaa99c"
66
}

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_download.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from azure.core.tracing.common import with_current_context
1818
from ._shared.request_handlers import validate_and_format_range_headers
1919
from ._shared.response_handlers import parse_length_from_content_range, process_storage_error
20+
from ._shared.constants import DEFAULT_MAX_CONCURRENCY
2021

2122
if TYPE_CHECKING:
2223
from ._generated.operations import FileOperations
@@ -217,7 +218,7 @@ def __init__(
217218
start_range: Optional[int] = None,
218219
end_range: Optional[int] = None,
219220
validate_content: bool = None, # type: ignore [assignment]
220-
max_concurrency: int = 1,
221+
max_concurrency: Optional[int] = None,
221222
name: str = None, # type: ignore [assignment]
222223
path: str = None, # type: ignore [assignment]
223224
share: str = None, # type: ignore [assignment]
@@ -233,7 +234,7 @@ def __init__(
233234
self._config = config
234235
self._start_range = start_range
235236
self._end_range = end_range
236-
self._max_concurrency = max_concurrency
237+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
237238
self._encoding = encoding
238239
self._validate_content = validate_content
239240
self._progress_hook = kwargs.pop('progress_hook', None)
@@ -398,7 +399,7 @@ def readall(self) -> bytes:
398399
return data.decode(self._encoding) # type: ignore [return-value]
399400
return data
400401

401-
def content_as_bytes(self, max_concurrency=1):
402+
def content_as_bytes(self, max_concurrency=None):
402403
"""DEPRECATED: Download the contents of this file.
403404
404405
This operation is blocking until all data is downloaded.
@@ -414,10 +415,10 @@ def content_as_bytes(self, max_concurrency=1):
414415
"content_as_bytes is deprecated, use readall instead",
415416
DeprecationWarning
416417
)
417-
self._max_concurrency = max_concurrency
418+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
418419
return self.readall()
419420

420-
def content_as_text(self, max_concurrency=1, encoding="UTF-8"):
421+
def content_as_text(self, max_concurrency=None, encoding="UTF-8"):
421422
"""DEPRECATED: Download the contents of this file, and decode as text.
422423
423424
This operation is blocking until all data is downloaded.
@@ -435,7 +436,7 @@ def content_as_text(self, max_concurrency=1, encoding="UTF-8"):
435436
"content_as_text is deprecated, use readall instead",
436437
DeprecationWarning
437438
)
438-
self._max_concurrency = max_concurrency
439+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
439440
self._encoding = encoding
440441
return self.readall()
441442

@@ -501,7 +502,7 @@ def readinto(self, stream: IO[bytes]) -> int:
501502
downloader.process_chunk(chunk)
502503
return self.size
503504

504-
def download_to_stream(self, stream, max_concurrency=1):
505+
def download_to_stream(self, stream, max_concurrency=None):
505506
"""DEPRECATED: Download the contents of this file to a stream.
506507
507508
This method is deprecated, use func:`readinto` instead.
@@ -519,6 +520,6 @@ def download_to_stream(self, stream, max_concurrency=1):
519520
"download_to_stream is deprecated, use readinto instead",
520521
DeprecationWarning
521522
)
522-
self._max_concurrency = max_concurrency
523+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
523524
self.readinto(stream)
524525
return self.properties

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
get_source_access_conditions
4242
)
4343
from ._shared.base_client import StorageAccountHostsMixin, parse_connection_str, parse_query
44+
from ._shared.constants import DEFAULT_MAX_CONCURRENCY
4445
from ._shared.request_handlers import add_metadata_headers, get_length
4546
from ._shared.response_handlers import return_response_headers, process_storage_error
4647
from ._shared.uploads import IterStreamer, FileChunkUploader, upload_data_chunks
@@ -594,7 +595,9 @@ def upload_file(
594595
"""
595596
metadata = kwargs.pop('metadata', None)
596597
content_settings = kwargs.pop('content_settings', None)
597-
max_concurrency = kwargs.pop('max_concurrency', 1)
598+
max_concurrency = kwargs.pop('max_concurrency', None)
599+
if max_concurrency is None:
600+
max_concurrency = DEFAULT_MAX_CONCURRENCY
598601
validate_content = kwargs.pop('validate_content', False)
599602
progress_hook = kwargs.pop('progress_hook', None)
600603
timeout = kwargs.pop('timeout', None)

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_file_client.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class ShareFileClient(StorageAccountHostsMixin):
150150
metadata: Optional[Dict[str, str]] = None,
151151
content_settings: Optional[ContentSettings] = None,
152152
validate_content: bool = False,
153-
max_concurrency: int = 1,
153+
max_concurrency: Optional[int] = None,
154154
lease: Optional[Union[ShareLeaseClient, str]] = None,
155155
progress_hook: Optional[Callable[[int, Optional[int]], None]] = None,
156156
encoding: str = "UTF-8",
@@ -196,7 +196,7 @@ class ShareFileClient(StorageAccountHostsMixin):
196196
offset: Optional[int] = None,
197197
length: Optional[int] = None,
198198
*,
199-
max_concurrency: int = 1,
199+
max_concurrency: Optional[int] = None,
200200
validate_content: bool = False,
201201
lease: Optional[Union[ShareLeaseClient, str]] = None,
202202
progress_hook: Optional[Callable[[int, Optional[int]], None]] = None,

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@
1818
STORAGE_OAUTH_SCOPE = "https://storage.azure.com/.default"
1919

2020
SERVICE_HOST_BASE = "core.windows.net"
21+
22+
DEFAULT_MAX_CONCURRENCY = 1

sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_download_async.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from .._download import _ChunkDownloader
2222
from .._shared.request_handlers import validate_and_format_range_headers
2323
from .._shared.response_handlers import parse_length_from_content_range, process_storage_error
24+
from .._shared.constants import DEFAULT_MAX_CONCURRENCY
2425

2526
if TYPE_CHECKING:
2627
from .._generated.aio.operations import FileOperations
@@ -178,7 +179,7 @@ def __init__(
178179
start_range: Optional[int] = None,
179180
end_range: Optional[int] = None,
180181
validate_content: bool = None, # type: ignore [assignment]
181-
max_concurrency: int = 1,
182+
max_concurrency: Optional[int] = None,
182183
name: str = None, # type: ignore [assignment]
183184
path: str = None, # type: ignore [assignment]
184185
share: str = None, # type: ignore [assignment]
@@ -194,7 +195,7 @@ def __init__(
194195
self._config = config
195196
self._start_range = start_range
196197
self._end_range = end_range
197-
self._max_concurrency = max_concurrency
198+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
198199
self._encoding = encoding
199200
self._validate_content = validate_content
200201
self._progress_hook = kwargs.pop('progress_hook', None)
@@ -358,7 +359,7 @@ async def readall(self) -> bytes:
358359
return data.decode(self._encoding) # type: ignore [return-value]
359360
return data
360361

361-
async def content_as_bytes(self, max_concurrency=1):
362+
async def content_as_bytes(self, max_concurrency=None):
362363
"""DEPRECATED: Download the contents of this file.
363364
364365
This operation is blocking until all data is downloaded.
@@ -374,10 +375,10 @@ async def content_as_bytes(self, max_concurrency=1):
374375
"content_as_bytes is deprecated, use readall instead",
375376
DeprecationWarning
376377
)
377-
self._max_concurrency = max_concurrency
378+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
378379
return await self.readall()
379380

380-
async def content_as_text(self, max_concurrency=1, encoding="UTF-8"):
381+
async def content_as_text(self, max_concurrency=None, encoding="UTF-8"):
381382
"""DEPRECATED: Download the contents of this file, and decode as text.
382383
383384
This operation is blocking until all data is downloaded.
@@ -395,7 +396,7 @@ async def content_as_text(self, max_concurrency=1, encoding="UTF-8"):
395396
"content_as_text is deprecated, use readall instead",
396397
DeprecationWarning
397398
)
398-
self._max_concurrency = max_concurrency
399+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
399400
self._encoding = encoding
400401
return await self.readall()
401402

@@ -480,7 +481,7 @@ async def readinto(self, stream: IO[bytes]) -> int:
480481
process_storage_error(error)
481482
return self.size
482483

483-
async def download_to_stream(self, stream, max_concurrency=1):
484+
async def download_to_stream(self, stream, max_concurrency=None):
484485
"""Download the contents of this file to a stream.
485486
486487
This method is deprecated, use func:`readinto` instead.
@@ -498,6 +499,6 @@ async def download_to_stream(self, stream, max_concurrency=1):
498499
"download_to_stream is deprecated, use readinto instead",
499500
DeprecationWarning
500501
)
501-
self._max_concurrency = max_concurrency
502+
self._max_concurrency = max_concurrency if max_concurrency is not None else DEFAULT_MAX_CONCURRENCY
502503
await self.readinto(stream)
503504
return self.properties

sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
)
4444
from .._shared.base_client import StorageAccountHostsMixin, parse_query
4545
from .._shared.base_client_async import AsyncStorageAccountHostsMixin, parse_connection_str
46+
from .._shared.constants import DEFAULT_MAX_CONCURRENCY
4647
from .._shared.policies_async import ExponentialRetry
4748
from .._shared.request_handlers import add_metadata_headers, get_length
4849
from .._shared.response_handlers import process_storage_error, return_response_headers
@@ -588,7 +589,9 @@ async def upload_file(
588589
"""
589590
metadata = kwargs.pop('metadata', None)
590591
content_settings = kwargs.pop('content_settings', None)
591-
max_concurrency = kwargs.pop('max_concurrency', 1)
592+
max_concurrency = kwargs.pop('max_concurrency', None)
593+
if max_concurrency is None:
594+
max_concurrency = DEFAULT_MAX_CONCURRENCY
592595
validate_content = kwargs.pop('validate_content', False)
593596
progress_hook = kwargs.pop('progress_hook', None)
594597
timeout = kwargs.pop('timeout', None)

sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_file_client_async.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class ShareFileClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin):
150150
metadata: Optional[Dict[str, str]] = None,
151151
content_settings: Optional[ContentSettings] = None,
152152
validate_content: bool = False,
153-
max_concurrency: int = 1,
153+
max_concurrency: Optional[int] = None,
154154
lease: Optional[Union[ShareLeaseClient, str]] = None,
155155
progress_hook: Optional[Callable[[int, Optional[int]], Awaitable[None]]] = None,
156156
encoding: str = "UTF-8",
@@ -196,7 +196,7 @@ class ShareFileClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin):
196196
offset: Optional[int] = None,
197197
length: Optional[int] = None,
198198
*,
199-
max_concurrency: int = 1,
199+
max_concurrency: Optional[int] = None,
200200
validate_content: bool = False,
201201
lease: Optional[Union[ShareLeaseClient, str]] = None,
202202
progress_hook: Optional[Callable[[int, Optional[int]], Awaitable[None]]] = None,

sdk/storage/azure-storage-file-share/tests/test_file.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4015,4 +4015,49 @@ def test_download_file_no_decompress_chunks(self, **kwargs):
40154015
result = file_client.download_file(decompress=False).readall()
40164016
assert result == compressed_data
40174017

4018+
@FileSharePreparer()
4019+
@recorded_by_proxy
4020+
def test_upload_file_with_none_max_concurrency(self, **kwargs):
4021+
storage_account_name = kwargs.pop("storage_account_name")
4022+
storage_account_key = kwargs.pop("storage_account_key")
4023+
4024+
self._setup(storage_account_name, storage_account_key)
4025+
file_name = self._get_file_reference()
4026+
file_client = ShareFileClient(
4027+
self.account_url(storage_account_name, "file"),
4028+
share_name=self.share_name,
4029+
file_path=file_name,
4030+
credential=storage_account_key.secret,
4031+
max_range_size=4 * 1024)
4032+
4033+
data = b"hello world"
4034+
4035+
# max_concurrency=None should not raise TypeError
4036+
file_client.upload_file(data, max_concurrency=None)
4037+
4038+
self.assertFileEqual(file_client, data)
4039+
4040+
@FileSharePreparer()
4041+
@recorded_by_proxy
4042+
def test_download_file_with_none_max_concurrency(self, **kwargs):
4043+
storage_account_name = kwargs.pop("storage_account_name")
4044+
storage_account_key = kwargs.pop("storage_account_key")
4045+
4046+
self._setup(storage_account_name, storage_account_key)
4047+
file_name = self._get_file_reference()
4048+
file_client = ShareFileClient(
4049+
self.account_url(storage_account_name, "file"),
4050+
share_name=self.share_name,
4051+
file_path=file_name,
4052+
credential=storage_account_key.secret,
4053+
max_range_size=4 * 1024)
4054+
4055+
data = b"hello world"
4056+
file_client.upload_file(data)
4057+
4058+
# max_concurrency=None should not raise TypeError
4059+
content = file_client.download_file(max_concurrency=None).readall()
4060+
4061+
assert content == data
4062+
40184063
# ------------------------------------------------------------------------------

sdk/storage/azure-storage-file-share/tests/test_file_async.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4141,3 +4141,50 @@ async def test_download_file_no_decompress_chunks(self, **kwargs):
41414141

41424142
result = await (await file_client.download_file(decompress=False)).readall()
41434143
assert result == compressed_data
4144+
4145+
@FileSharePreparer()
4146+
@recorded_by_proxy_async
4147+
async def test_upload_file_with_none_max_concurrency(self, **kwargs):
4148+
storage_account_name = kwargs.pop("storage_account_name")
4149+
storage_account_key = kwargs.pop("storage_account_key")
4150+
4151+
self._setup(storage_account_name, storage_account_key)
4152+
await self._setup_share(storage_account_name, storage_account_key)
4153+
file_name = self._get_file_reference()
4154+
file_client = ShareFileClient(
4155+
self.account_url(storage_account_name, "file"),
4156+
share_name=self.share_name,
4157+
file_path=file_name,
4158+
credential=storage_account_key.secret,
4159+
max_range_size=4 * 1024)
4160+
4161+
data = b"hello world"
4162+
4163+
# max_concurrency=None should not raise TypeError
4164+
await file_client.upload_file(data, max_concurrency=None)
4165+
4166+
await self.assertFileEqual(file_client, data)
4167+
4168+
@FileSharePreparer()
4169+
@recorded_by_proxy_async
4170+
async def test_download_file_with_none_max_concurrency(self, **kwargs):
4171+
storage_account_name = kwargs.pop("storage_account_name")
4172+
storage_account_key = kwargs.pop("storage_account_key")
4173+
4174+
self._setup(storage_account_name, storage_account_key)
4175+
await self._setup_share(storage_account_name, storage_account_key)
4176+
file_name = self._get_file_reference()
4177+
file_client = ShareFileClient(
4178+
self.account_url(storage_account_name, "file"),
4179+
share_name=self.share_name,
4180+
file_path=file_name,
4181+
credential=storage_account_key.secret,
4182+
max_range_size=4 * 1024)
4183+
4184+
data = b"hello world"
4185+
await file_client.upload_file(data)
4186+
4187+
# max_concurrency=None should not raise TypeError
4188+
content = await (await file_client.download_file(max_concurrency=None)).readall()
4189+
4190+
assert content == data

0 commit comments

Comments
 (0)