azure-storage-blob 12.23.0b1__py3-none-any.whl → 12.24.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- azure/storage/blob/_blob_client.py +34 -10
- azure/storage/blob/_blob_client_helpers.py +7 -3
- azure/storage/blob/_blob_service_client.py +1 -1
- azure/storage/blob/_container_client.py +8 -2
- azure/storage/blob/_container_client_helpers.py +11 -6
- azure/storage/blob/_deserialize.py +2 -2
- azure/storage/blob/_encryption.py +15 -10
- azure/storage/blob/_generated/_azure_blob_storage.py +3 -2
- azure/storage/blob/_generated/_configuration.py +2 -2
- azure/storage/blob/_generated/_serialization.py +267 -150
- azure/storage/blob/_generated/aio/_azure_blob_storage.py +3 -2
- azure/storage/blob/_generated/aio/_configuration.py +2 -2
- azure/storage/blob/_generated/aio/operations/_append_blob_operations.py +23 -11
- azure/storage/blob/_generated/aio/operations/_blob_operations.py +137 -73
- azure/storage/blob/_generated/aio/operations/_block_blob_operations.py +42 -16
- azure/storage/blob/_generated/aio/operations/_container_operations.py +49 -44
- azure/storage/blob/_generated/aio/operations/_page_blob_operations.py +35 -23
- azure/storage/blob/_generated/aio/operations/_service_operations.py +30 -25
- azure/storage/blob/_generated/models/_azure_blob_storage_enums.py +1 -0
- azure/storage/blob/_generated/operations/_append_blob_operations.py +35 -15
- azure/storage/blob/_generated/operations/_blob_operations.py +187 -98
- azure/storage/blob/_generated/operations/_block_blob_operations.py +64 -22
- azure/storage/blob/_generated/operations/_container_operations.py +67 -62
- azure/storage/blob/_generated/operations/_page_blob_operations.py +52 -32
- azure/storage/blob/_generated/operations/_service_operations.py +38 -33
- azure/storage/blob/_list_blobs_helper.py +1 -1
- azure/storage/blob/_models.py +4 -3
- azure/storage/blob/_serialize.py +1 -0
- azure/storage/blob/_shared/avro/schema.py +1 -0
- azure/storage/blob/_shared/base_client.py +10 -8
- azure/storage/blob/_shared/base_client_async.py +5 -5
- azure/storage/blob/_shared/models.py +5 -2
- azure/storage/blob/_shared/policies.py +14 -16
- azure/storage/blob/_shared/policies_async.py +19 -6
- azure/storage/blob/_shared/request_handlers.py +2 -3
- azure/storage/blob/_shared/response_handlers.py +2 -2
- azure/storage/blob/_shared/uploads.py +4 -4
- azure/storage/blob/_shared/uploads_async.py +4 -4
- azure/storage/blob/_shared_access_signature.py +0 -1
- azure/storage/blob/_version.py +1 -1
- azure/storage/blob/aio/_blob_client_async.py +36 -13
- azure/storage/blob/aio/_blob_service_client_async.py +7 -3
- azure/storage/blob/aio/_container_client_async.py +10 -4
- azure/storage/blob/aio/_download_async.py +94 -71
- azure/storage/blob/aio/_lease_async.py +1 -1
- azure/storage/blob/aio/_list_blobs_helper.py +1 -2
- azure/storage/blob/aio/_models.py +1 -2
- {azure_storage_blob-12.23.0b1.dist-info → azure_storage_blob-12.24.0.dist-info}/METADATA +10 -10
- azure_storage_blob-12.24.0.dist-info/RECORD +84 -0
- {azure_storage_blob-12.23.0b1.dist-info → azure_storage_blob-12.24.0.dist-info}/WHEEL +1 -1
- azure/storage/blob/_generated/_vendor.py +0 -16
- azure_storage_blob-12.23.0b1.dist-info/RECORD +0 -85
- {azure_storage_blob-12.23.0b1.dist-info → azure_storage_blob-12.24.0.dist-info}/LICENSE +0 -0
- {azure_storage_blob-12.23.0b1.dist-info → azure_storage_blob-12.24.0.dist-info}/top_level.txt +0 -0
@@ -15,17 +15,17 @@ from azure.core.exceptions import (
|
|
15
15
|
ResourceExistsError,
|
16
16
|
ResourceNotFoundError,
|
17
17
|
ResourceNotModifiedError,
|
18
|
+
StreamClosedError,
|
19
|
+
StreamConsumedError,
|
18
20
|
map_error,
|
19
21
|
)
|
20
22
|
from azure.core.pipeline import PipelineResponse
|
21
|
-
from azure.core.
|
22
|
-
from azure.core.rest import HttpRequest
|
23
|
+
from azure.core.rest import HttpRequest, HttpResponse
|
23
24
|
from azure.core.tracing.decorator import distributed_trace
|
24
25
|
from azure.core.utils import case_insensitive_dict
|
25
26
|
|
26
27
|
from .. import models as _models
|
27
28
|
from .._serialization import Serializer
|
28
|
-
from .._vendor import _convert_request
|
29
29
|
|
30
30
|
if sys.version_info >= (3, 9):
|
31
31
|
from collections.abc import MutableMapping
|
@@ -47,7 +47,7 @@ def build_set_properties_request(
|
|
47
47
|
restype: Literal["service"] = kwargs.pop("restype", _params.pop("restype", "service"))
|
48
48
|
comp: Literal["properties"] = kwargs.pop("comp", _params.pop("comp", "properties"))
|
49
49
|
content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
|
50
|
-
version: Literal["
|
50
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
51
51
|
accept = _headers.pop("Accept", "application/xml")
|
52
52
|
|
53
53
|
# Construct URL
|
@@ -83,7 +83,7 @@ def build_get_properties_request(
|
|
83
83
|
|
84
84
|
restype: Literal["service"] = kwargs.pop("restype", _params.pop("restype", "service"))
|
85
85
|
comp: Literal["properties"] = kwargs.pop("comp", _params.pop("comp", "properties"))
|
86
|
-
version: Literal["
|
86
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
87
87
|
accept = _headers.pop("Accept", "application/xml")
|
88
88
|
|
89
89
|
# Construct URL
|
@@ -117,7 +117,7 @@ def build_get_statistics_request(
|
|
117
117
|
|
118
118
|
restype: Literal["service"] = kwargs.pop("restype", _params.pop("restype", "service"))
|
119
119
|
comp: Literal["stats"] = kwargs.pop("comp", _params.pop("comp", "stats"))
|
120
|
-
version: Literal["
|
120
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
121
121
|
accept = _headers.pop("Accept", "application/xml")
|
122
122
|
|
123
123
|
# Construct URL
|
@@ -158,7 +158,7 @@ def build_list_containers_segment_request(
|
|
158
158
|
_params = case_insensitive_dict(kwargs.pop("params", {}) or {})
|
159
159
|
|
160
160
|
comp: Literal["list"] = kwargs.pop("comp", _params.pop("comp", "list"))
|
161
|
-
version: Literal["
|
161
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
162
162
|
accept = _headers.pop("Accept", "application/xml")
|
163
163
|
|
164
164
|
# Construct URL
|
@@ -200,7 +200,7 @@ def build_get_user_delegation_key_request(
|
|
200
200
|
restype: Literal["service"] = kwargs.pop("restype", _params.pop("restype", "service"))
|
201
201
|
comp: Literal["userdelegationkey"] = kwargs.pop("comp", _params.pop("comp", "userdelegationkey"))
|
202
202
|
content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
|
203
|
-
version: Literal["
|
203
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
204
204
|
accept = _headers.pop("Accept", "application/xml")
|
205
205
|
|
206
206
|
# Construct URL
|
@@ -236,7 +236,7 @@ def build_get_account_info_request(
|
|
236
236
|
|
237
237
|
restype: Literal["account"] = kwargs.pop("restype", _params.pop("restype", "account"))
|
238
238
|
comp: Literal["properties"] = kwargs.pop("comp", _params.pop("comp", "properties"))
|
239
|
-
version: Literal["
|
239
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
240
240
|
accept = _headers.pop("Accept", "application/xml")
|
241
241
|
|
242
242
|
# Construct URL
|
@@ -276,7 +276,7 @@ def build_submit_batch_request(
|
|
276
276
|
|
277
277
|
comp: Literal["batch"] = kwargs.pop("comp", _params.pop("comp", "batch"))
|
278
278
|
multipart_content_type: Optional[str] = kwargs.pop("multipart_content_type", _headers.pop("Content-Type", None))
|
279
|
-
version: Literal["
|
279
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
280
280
|
accept = _headers.pop("Accept", "application/xml")
|
281
281
|
|
282
282
|
# Construct URL
|
@@ -319,7 +319,7 @@ def build_filter_blobs_request(
|
|
319
319
|
_params = case_insensitive_dict(kwargs.pop("params", {}) or {})
|
320
320
|
|
321
321
|
comp: Literal["blobs"] = kwargs.pop("comp", _params.pop("comp", "blobs"))
|
322
|
-
version: Literal["
|
322
|
+
version: Literal["2025-01-05"] = kwargs.pop("version", _headers.pop("x-ms-version", "2025-01-05"))
|
323
323
|
accept = _headers.pop("Accept", "application/xml")
|
324
324
|
|
325
325
|
# Construct URL
|
@@ -379,6 +379,7 @@ class ServiceOperations:
|
|
379
379
|
request_id_parameter: Optional[str] = None,
|
380
380
|
**kwargs: Any
|
381
381
|
) -> None:
|
382
|
+
# pylint: disable=line-too-long
|
382
383
|
"""Sets properties for a storage account's Blob service endpoint, including properties for Storage
|
383
384
|
Analytics and CORS (Cross-Origin Resource Sharing) rules.
|
384
385
|
|
@@ -397,7 +398,7 @@ class ServiceOperations:
|
|
397
398
|
:rtype: None
|
398
399
|
:raises ~azure.core.exceptions.HttpResponseError:
|
399
400
|
"""
|
400
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
401
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
401
402
|
401: ClientAuthenticationError,
|
402
403
|
404: ResourceNotFoundError,
|
403
404
|
409: ResourceExistsError,
|
@@ -427,7 +428,6 @@ class ServiceOperations:
|
|
427
428
|
headers=_headers,
|
428
429
|
params=_params,
|
429
430
|
)
|
430
|
-
_request = _convert_request(_request)
|
431
431
|
_request.url = self._client.format_url(_request.url)
|
432
432
|
|
433
433
|
_stream = False
|
@@ -456,6 +456,7 @@ class ServiceOperations:
|
|
456
456
|
def get_properties(
|
457
457
|
self, timeout: Optional[int] = None, request_id_parameter: Optional[str] = None, **kwargs: Any
|
458
458
|
) -> _models.StorageServiceProperties:
|
459
|
+
# pylint: disable=line-too-long
|
459
460
|
"""gets the properties of a storage account's Blob service, including properties for Storage
|
460
461
|
Analytics and CORS (Cross-Origin Resource Sharing) rules.
|
461
462
|
|
@@ -472,7 +473,7 @@ class ServiceOperations:
|
|
472
473
|
:rtype: ~azure.storage.blob.models.StorageServiceProperties
|
473
474
|
:raises ~azure.core.exceptions.HttpResponseError:
|
474
475
|
"""
|
475
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
476
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
476
477
|
401: ClientAuthenticationError,
|
477
478
|
404: ResourceNotFoundError,
|
478
479
|
409: ResourceExistsError,
|
@@ -497,7 +498,6 @@ class ServiceOperations:
|
|
497
498
|
headers=_headers,
|
498
499
|
params=_params,
|
499
500
|
)
|
500
|
-
_request = _convert_request(_request)
|
501
501
|
_request.url = self._client.format_url(_request.url)
|
502
502
|
|
503
503
|
_stream = False
|
@@ -519,7 +519,7 @@ class ServiceOperations:
|
|
519
519
|
response_headers["x-ms-request-id"] = self._deserialize("str", response.headers.get("x-ms-request-id"))
|
520
520
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
521
521
|
|
522
|
-
deserialized = self._deserialize("StorageServiceProperties", pipeline_response)
|
522
|
+
deserialized = self._deserialize("StorageServiceProperties", pipeline_response.http_response)
|
523
523
|
|
524
524
|
if cls:
|
525
525
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -530,6 +530,7 @@ class ServiceOperations:
|
|
530
530
|
def get_statistics(
|
531
531
|
self, timeout: Optional[int] = None, request_id_parameter: Optional[str] = None, **kwargs: Any
|
532
532
|
) -> _models.StorageServiceStats:
|
533
|
+
# pylint: disable=line-too-long
|
533
534
|
"""Retrieves statistics related to replication for the Blob service. It is only available on the
|
534
535
|
secondary location endpoint when read-access geo-redundant replication is enabled for the
|
535
536
|
storage account.
|
@@ -547,7 +548,7 @@ class ServiceOperations:
|
|
547
548
|
:rtype: ~azure.storage.blob.models.StorageServiceStats
|
548
549
|
:raises ~azure.core.exceptions.HttpResponseError:
|
549
550
|
"""
|
550
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
551
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
551
552
|
401: ClientAuthenticationError,
|
552
553
|
404: ResourceNotFoundError,
|
553
554
|
409: ResourceExistsError,
|
@@ -572,7 +573,6 @@ class ServiceOperations:
|
|
572
573
|
headers=_headers,
|
573
574
|
params=_params,
|
574
575
|
)
|
575
|
-
_request = _convert_request(_request)
|
576
576
|
_request.url = self._client.format_url(_request.url)
|
577
577
|
|
578
578
|
_stream = False
|
@@ -595,7 +595,7 @@ class ServiceOperations:
|
|
595
595
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
596
596
|
response_headers["Date"] = self._deserialize("rfc-1123", response.headers.get("Date"))
|
597
597
|
|
598
|
-
deserialized = self._deserialize("StorageServiceStats", pipeline_response)
|
598
|
+
deserialized = self._deserialize("StorageServiceStats", pipeline_response.http_response)
|
599
599
|
|
600
600
|
if cls:
|
601
601
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -613,6 +613,7 @@ class ServiceOperations:
|
|
613
613
|
request_id_parameter: Optional[str] = None,
|
614
614
|
**kwargs: Any
|
615
615
|
) -> _models.ListContainersSegmentResponse:
|
616
|
+
# pylint: disable=line-too-long
|
616
617
|
"""The List Containers Segment operation returns a list of the containers under the specified
|
617
618
|
account.
|
618
619
|
|
@@ -649,7 +650,7 @@ class ServiceOperations:
|
|
649
650
|
:rtype: ~azure.storage.blob.models.ListContainersSegmentResponse
|
650
651
|
:raises ~azure.core.exceptions.HttpResponseError:
|
651
652
|
"""
|
652
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
653
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
653
654
|
401: ClientAuthenticationError,
|
654
655
|
404: ResourceNotFoundError,
|
655
656
|
409: ResourceExistsError,
|
@@ -676,7 +677,6 @@ class ServiceOperations:
|
|
676
677
|
headers=_headers,
|
677
678
|
params=_params,
|
678
679
|
)
|
679
|
-
_request = _convert_request(_request)
|
680
680
|
_request.url = self._client.format_url(_request.url)
|
681
681
|
|
682
682
|
_stream = False
|
@@ -698,7 +698,7 @@ class ServiceOperations:
|
|
698
698
|
response_headers["x-ms-request-id"] = self._deserialize("str", response.headers.get("x-ms-request-id"))
|
699
699
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
700
700
|
|
701
|
-
deserialized = self._deserialize("ListContainersSegmentResponse", pipeline_response)
|
701
|
+
deserialized = self._deserialize("ListContainersSegmentResponse", pipeline_response.http_response)
|
702
702
|
|
703
703
|
if cls:
|
704
704
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -713,6 +713,7 @@ class ServiceOperations:
|
|
713
713
|
request_id_parameter: Optional[str] = None,
|
714
714
|
**kwargs: Any
|
715
715
|
) -> _models.UserDelegationKey:
|
716
|
+
# pylint: disable=line-too-long
|
716
717
|
"""Retrieves a user delegation key for the Blob service. This is only a valid operation when using
|
717
718
|
bearer token authentication.
|
718
719
|
|
@@ -731,7 +732,7 @@ class ServiceOperations:
|
|
731
732
|
:rtype: ~azure.storage.blob.models.UserDelegationKey
|
732
733
|
:raises ~azure.core.exceptions.HttpResponseError:
|
733
734
|
"""
|
734
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
735
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
735
736
|
401: ClientAuthenticationError,
|
736
737
|
404: ResourceNotFoundError,
|
737
738
|
409: ResourceExistsError,
|
@@ -761,7 +762,6 @@ class ServiceOperations:
|
|
761
762
|
headers=_headers,
|
762
763
|
params=_params,
|
763
764
|
)
|
764
|
-
_request = _convert_request(_request)
|
765
765
|
_request.url = self._client.format_url(_request.url)
|
766
766
|
|
767
767
|
_stream = False
|
@@ -784,7 +784,7 @@ class ServiceOperations:
|
|
784
784
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
785
785
|
response_headers["Date"] = self._deserialize("rfc-1123", response.headers.get("Date"))
|
786
786
|
|
787
|
-
deserialized = self._deserialize("UserDelegationKey", pipeline_response)
|
787
|
+
deserialized = self._deserialize("UserDelegationKey", pipeline_response.http_response)
|
788
788
|
|
789
789
|
if cls:
|
790
790
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -795,6 +795,7 @@ class ServiceOperations:
|
|
795
795
|
def get_account_info( # pylint: disable=inconsistent-return-statements
|
796
796
|
self, timeout: Optional[int] = None, request_id_parameter: Optional[str] = None, **kwargs: Any
|
797
797
|
) -> None:
|
798
|
+
# pylint: disable=line-too-long
|
798
799
|
"""Returns the sku name and account kind.
|
799
800
|
|
800
801
|
:param timeout: The timeout parameter is expressed in seconds. For more information, see
|
@@ -810,7 +811,7 @@ class ServiceOperations:
|
|
810
811
|
:rtype: None
|
811
812
|
:raises ~azure.core.exceptions.HttpResponseError:
|
812
813
|
"""
|
813
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
814
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
814
815
|
401: ClientAuthenticationError,
|
815
816
|
404: ResourceNotFoundError,
|
816
817
|
409: ResourceExistsError,
|
@@ -835,7 +836,6 @@ class ServiceOperations:
|
|
835
836
|
headers=_headers,
|
836
837
|
params=_params,
|
837
838
|
)
|
838
|
-
_request = _convert_request(_request)
|
839
839
|
_request.url = self._client.format_url(_request.url)
|
840
840
|
|
841
841
|
_stream = False
|
@@ -873,6 +873,7 @@ class ServiceOperations:
|
|
873
873
|
request_id_parameter: Optional[str] = None,
|
874
874
|
**kwargs: Any
|
875
875
|
) -> Iterator[bytes]:
|
876
|
+
# pylint: disable=line-too-long
|
876
877
|
"""The Batch operation allows multiple API calls to be embedded into a single HTTP request.
|
877
878
|
|
878
879
|
:param content_length: The length of the request. Required.
|
@@ -892,7 +893,7 @@ class ServiceOperations:
|
|
892
893
|
:rtype: Iterator[bytes]
|
893
894
|
:raises ~azure.core.exceptions.HttpResponseError:
|
894
895
|
"""
|
895
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
896
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
896
897
|
401: ClientAuthenticationError,
|
897
898
|
404: ResourceNotFoundError,
|
898
899
|
409: ResourceExistsError,
|
@@ -923,9 +924,9 @@ class ServiceOperations:
|
|
923
924
|
headers=_headers,
|
924
925
|
params=_params,
|
925
926
|
)
|
926
|
-
_request = _convert_request(_request)
|
927
927
|
_request.url = self._client.format_url(_request.url)
|
928
928
|
|
929
|
+
_decompress = kwargs.pop("decompress", True)
|
929
930
|
_stream = True
|
930
931
|
pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access
|
931
932
|
_request, stream=_stream, **kwargs
|
@@ -934,6 +935,10 @@ class ServiceOperations:
|
|
934
935
|
response = pipeline_response.http_response
|
935
936
|
|
936
937
|
if response.status_code not in [200]:
|
938
|
+
try:
|
939
|
+
response.read() # Load the body in memory and close the socket
|
940
|
+
except (StreamConsumedError, StreamClosedError):
|
941
|
+
pass
|
937
942
|
map_error(status_code=response.status_code, response=response, error_map=error_map)
|
938
943
|
error = self._deserialize.failsafe_deserialize(_models.StorageError, pipeline_response)
|
939
944
|
raise HttpResponseError(response=response, model=error)
|
@@ -943,7 +948,7 @@ class ServiceOperations:
|
|
943
948
|
response_headers["x-ms-request-id"] = self._deserialize("str", response.headers.get("x-ms-request-id"))
|
944
949
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
945
950
|
|
946
|
-
deserialized = response.stream_download(self._client._pipeline)
|
951
|
+
deserialized = response.stream_download(self._client._pipeline, decompress=_decompress)
|
947
952
|
|
948
953
|
if cls:
|
949
954
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -961,6 +966,7 @@ class ServiceOperations:
|
|
961
966
|
include: Optional[List[Union[str, _models.FilterBlobsIncludeItem]]] = None,
|
962
967
|
**kwargs: Any
|
963
968
|
) -> _models.FilterBlobSegment:
|
969
|
+
# pylint: disable=line-too-long
|
964
970
|
"""The Filter Blobs operation enables callers to list blobs across all containers whose tags match
|
965
971
|
a given search expression. Filter blobs searches across all containers within a storage
|
966
972
|
account but can be scoped within the expression to a single container.
|
@@ -998,7 +1004,7 @@ class ServiceOperations:
|
|
998
1004
|
:rtype: ~azure.storage.blob.models.FilterBlobSegment
|
999
1005
|
:raises ~azure.core.exceptions.HttpResponseError:
|
1000
1006
|
"""
|
1001
|
-
error_map: MutableMapping[int, Type[HttpResponseError]] = {
|
1007
|
+
error_map: MutableMapping[int, Type[HttpResponseError]] = { # pylint: disable=unsubscriptable-object
|
1002
1008
|
401: ClientAuthenticationError,
|
1003
1009
|
404: ResourceNotFoundError,
|
1004
1010
|
409: ResourceExistsError,
|
@@ -1025,7 +1031,6 @@ class ServiceOperations:
|
|
1025
1031
|
headers=_headers,
|
1026
1032
|
params=_params,
|
1027
1033
|
)
|
1028
|
-
_request = _convert_request(_request)
|
1029
1034
|
_request.url = self._client.format_url(_request.url)
|
1030
1035
|
|
1031
1036
|
_stream = False
|
@@ -1048,7 +1053,7 @@ class ServiceOperations:
|
|
1048
1053
|
response_headers["x-ms-version"] = self._deserialize("str", response.headers.get("x-ms-version"))
|
1049
1054
|
response_headers["Date"] = self._deserialize("rfc-1123", response.headers.get("Date"))
|
1050
1055
|
|
1051
|
-
deserialized = self._deserialize("FilterBlobSegment", pipeline_response)
|
1056
|
+
deserialized = self._deserialize("FilterBlobSegment", pipeline_response.http_response)
|
1052
1057
|
|
1053
1058
|
if cls:
|
1054
1059
|
return cls(pipeline_response, deserialized, response_headers) # type: ignore
|
@@ -110,7 +110,7 @@ class BlobPropertiesPaged(PageIterator):
|
|
110
110
|
if isinstance(item, BlobProperties):
|
111
111
|
return item
|
112
112
|
if isinstance(item, BlobItemInternal):
|
113
|
-
blob = get_blob_properties_from_generated_code(item)
|
113
|
+
blob = get_blob_properties_from_generated_code(item)
|
114
114
|
blob.container = self.container # type: ignore [assignment]
|
115
115
|
return blob
|
116
116
|
return item
|
azure/storage/blob/_models.py
CHANGED
@@ -472,7 +472,7 @@ class ContainerProperties(DictMixin):
|
|
472
472
|
)
|
473
473
|
|
474
474
|
@classmethod
|
475
|
-
def _from_generated(cls, generated):
|
475
|
+
def _from_generated(cls, generated):
|
476
476
|
props = cls()
|
477
477
|
props.name = generated.name
|
478
478
|
props.last_modified = generated.properties.last_modified
|
@@ -934,7 +934,7 @@ class ContainerSasPermissions(object):
|
|
934
934
|
delete_previous_version: bool = False,
|
935
935
|
tag: bool = False,
|
936
936
|
**kwargs: Any
|
937
|
-
) -> None:
|
937
|
+
) -> None:
|
938
938
|
self.read = read
|
939
939
|
self.add = kwargs.pop('add', False)
|
940
940
|
self.create = kwargs.pop('create', False)
|
@@ -1443,7 +1443,8 @@ class BlobProperties(DictMixin):
|
|
1443
1443
|
self.snapshot = kwargs.get('x-ms-snapshot')
|
1444
1444
|
self.version_id = kwargs.get('x-ms-version-id')
|
1445
1445
|
self.is_current_version = kwargs.get('x-ms-is-current-version')
|
1446
|
-
self.blob_type = BlobType(kwargs['x-ms-blob-type']) if
|
1446
|
+
self.blob_type = BlobType(kwargs['x-ms-blob-type']) if (
|
1447
|
+
kwargs.get('x-ms-blob-type')) else None # type: ignore [assignment]
|
1447
1448
|
self.metadata = kwargs.get('metadata') # type: ignore [assignment]
|
1448
1449
|
self.encrypted_metadata = kwargs.get('encrypted_metadata')
|
1449
1450
|
self.last_modified = kwargs.get('Last-Modified') # type: ignore [assignment]
|
azure/storage/blob/_serialize.py
CHANGED
@@ -957,6 +957,7 @@ class RecordSchema(NamedSchema):
|
|
957
957
|
raise SchemaParseException(
|
958
958
|
f'Invalid record type: {record_type!r}.')
|
959
959
|
|
960
|
+
nested_names = []
|
960
961
|
if record_type in [RECORD, ERROR]:
|
961
962
|
avro_name = names.get_name(name=name, namespace=namespace)
|
962
963
|
nested_names = names.new_with_default_namespace(namespace=avro_name.namespace)
|
@@ -64,18 +64,19 @@ _SERVICE_PARAMS = {
|
|
64
64
|
}
|
65
65
|
|
66
66
|
|
67
|
-
class StorageAccountHostsMixin(object):
|
67
|
+
class StorageAccountHostsMixin(object):
|
68
68
|
_client: Any
|
69
69
|
def __init__(
|
70
70
|
self,
|
71
71
|
parsed_url: Any,
|
72
72
|
service: str,
|
73
|
-
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "AsyncTokenCredential", TokenCredential]] = None,
|
73
|
+
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "AsyncTokenCredential", TokenCredential]] = None, # pylint: disable=line-too-long
|
74
74
|
**kwargs: Any
|
75
75
|
) -> None:
|
76
76
|
self._location_mode = kwargs.get("_location_mode", LocationMode.PRIMARY)
|
77
77
|
self._hosts = kwargs.get("_hosts")
|
78
78
|
self.scheme = parsed_url.scheme
|
79
|
+
self._is_localhost = False
|
79
80
|
|
80
81
|
if service not in ["blob", "queue", "file-share", "dfs"]:
|
81
82
|
raise ValueError(f"Invalid service: {service}")
|
@@ -85,6 +86,7 @@ class StorageAccountHostsMixin(object): # pylint: disable=too-many-instance-att
|
|
85
86
|
self.account_name = account[0] if len(account) > 1 else None
|
86
87
|
if not self.account_name and parsed_url.netloc.startswith("localhost") \
|
87
88
|
or parsed_url.netloc.startswith("127.0.0.1"):
|
89
|
+
self._is_localhost = True
|
88
90
|
self.account_name = parsed_url.path.strip("/")
|
89
91
|
|
90
92
|
self.credential = _format_shared_key_credential(self.account_name, credential)
|
@@ -222,7 +224,7 @@ class StorageAccountHostsMixin(object): # pylint: disable=too-many-instance-att
|
|
222
224
|
return query_str.rstrip("?&"), credential
|
223
225
|
|
224
226
|
def _create_pipeline(
|
225
|
-
self, credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]] = None,
|
227
|
+
self, credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]] = None, # pylint: disable=line-too-long
|
226
228
|
**kwargs: Any
|
227
229
|
) -> Tuple[StorageConfiguration, Pipeline]:
|
228
230
|
self._credential_policy: Any = None
|
@@ -306,7 +308,7 @@ class StorageAccountHostsMixin(object): # pylint: disable=too-many-instance-att
|
|
306
308
|
enforce_https=False
|
307
309
|
)
|
308
310
|
|
309
|
-
Pipeline._prepare_multipart_mixed_request(request)
|
311
|
+
Pipeline._prepare_multipart_mixed_request(request) # pylint: disable=protected-access
|
310
312
|
body = serialize_batch_body(request.multipart_mixed_info[0], batch_id)
|
311
313
|
request.set_bytes_body(body)
|
312
314
|
|
@@ -356,13 +358,13 @@ class TransportWrapper(HttpTransport):
|
|
356
358
|
def __enter__(self):
|
357
359
|
pass
|
358
360
|
|
359
|
-
def __exit__(self, *args):
|
361
|
+
def __exit__(self, *args):
|
360
362
|
pass
|
361
363
|
|
362
364
|
|
363
365
|
def _format_shared_key_credential(
|
364
366
|
account_name: str,
|
365
|
-
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "AsyncTokenCredential", TokenCredential]] = None
|
367
|
+
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, "AsyncTokenCredential", TokenCredential]] = None # pylint: disable=line-too-long
|
366
368
|
) -> Any:
|
367
369
|
if isinstance(credential, str):
|
368
370
|
if not account_name:
|
@@ -381,9 +383,9 @@ def _format_shared_key_credential(
|
|
381
383
|
|
382
384
|
def parse_connection_str(
|
383
385
|
conn_str: str,
|
384
|
-
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]],
|
386
|
+
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]],
|
385
387
|
service: str
|
386
|
-
) -> Tuple[str, Optional[str], Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]]]:
|
388
|
+
) -> Tuple[str, Optional[str], Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, TokenCredential]]]: # pylint: disable=line-too-long
|
387
389
|
conn_str = conn_str.rstrip(";")
|
388
390
|
conn_settings_list = [s.split("=", 1) for s in conn_str.split(";")]
|
389
391
|
if any(len(tup) != 2 for tup in conn_settings_list):
|
@@ -127,16 +127,16 @@ class AsyncStorageAccountHostsMixin(object):
|
|
127
127
|
hosts = self._hosts
|
128
128
|
policies = [
|
129
129
|
QueueMessagePolicy(),
|
130
|
-
config.headers_policy,
|
131
130
|
config.proxy_policy,
|
132
131
|
config.user_agent_policy,
|
133
132
|
StorageContentValidation(),
|
134
|
-
StorageRequestHook(**kwargs),
|
135
|
-
self._credential_policy,
|
136
133
|
ContentDecodePolicy(response_encoding="utf-8"),
|
137
134
|
AsyncRedirectPolicy(**kwargs),
|
138
135
|
StorageHosts(hosts=hosts, **kwargs),
|
139
136
|
config.retry_policy,
|
137
|
+
config.headers_policy,
|
138
|
+
StorageRequestHook(**kwargs),
|
139
|
+
self._credential_policy,
|
140
140
|
config.logging_policy,
|
141
141
|
AsyncStorageResponseHook(**kwargs),
|
142
142
|
DistributedTracingPolicy(**kwargs),
|
@@ -207,7 +207,7 @@ class AsyncStorageAccountHostsMixin(object):
|
|
207
207
|
|
208
208
|
def parse_connection_str(
|
209
209
|
conn_str: str,
|
210
|
-
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential]],
|
210
|
+
credential: Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential]],
|
211
211
|
service: str
|
212
212
|
) -> Tuple[str, Optional[str], Optional[Union[str, Dict[str, str], AzureNamedKeyCredential, AzureSasCredential, AsyncTokenCredential]]]: # pylint: disable=line-too-long
|
213
213
|
conn_str = conn_str.rstrip(";")
|
@@ -276,5 +276,5 @@ class AsyncTransportWrapper(AsyncHttpTransport):
|
|
276
276
|
async def __aenter__(self):
|
277
277
|
pass
|
278
278
|
|
279
|
-
async def __aexit__(self, *args):
|
279
|
+
async def __aexit__(self, *args):
|
280
280
|
pass
|
@@ -70,6 +70,7 @@ class StorageErrorCode(str, Enum, metaclass=CaseInsensitiveEnumMeta):
|
|
70
70
|
|
71
71
|
# Blob values
|
72
72
|
APPEND_POSITION_CONDITION_NOT_MET = "AppendPositionConditionNotMet"
|
73
|
+
BLOB_ACCESS_TIER_NOT_SUPPORTED_FOR_ACCOUNT_TYPE = "BlobAccessTierNotSupportedForAccountType"
|
73
74
|
BLOB_ALREADY_EXISTS = "BlobAlreadyExists"
|
74
75
|
BLOB_NOT_FOUND = "BlobNotFound"
|
75
76
|
BLOB_OVERWRITTEN = "BlobOverwritten"
|
@@ -154,6 +155,8 @@ class StorageErrorCode(str, Enum, metaclass=CaseInsensitiveEnumMeta):
|
|
154
155
|
DELETE_PENDING = "DeletePending"
|
155
156
|
DIRECTORY_NOT_EMPTY = "DirectoryNotEmpty"
|
156
157
|
FILE_LOCK_CONFLICT = "FileLockConflict"
|
158
|
+
FILE_SHARE_PROVISIONED_BANDWIDTH_DOWNGRADE_NOT_ALLOWED = "FileShareProvisionedBandwidthDowngradeNotAllowed"
|
159
|
+
FILE_SHARE_PROVISIONED_IOPS_DOWNGRADE_NOT_ALLOWED = "FileShareProvisionedIopsDowngradeNotAllowed"
|
157
160
|
INVALID_FILE_OR_DIRECTORY_PATH_NAME = "InvalidFileOrDirectoryPathName"
|
158
161
|
PARENT_NOT_FOUND = "ParentNotFound"
|
159
162
|
READ_ONLY_ATTRIBUTE = "ReadOnlyAttribute"
|
@@ -311,7 +314,7 @@ class ResourceTypes(object):
|
|
311
314
|
res_object = 'o' in string
|
312
315
|
|
313
316
|
parsed = cls(res_service, res_container, res_object)
|
314
|
-
parsed._str = string
|
317
|
+
parsed._str = string
|
315
318
|
return parsed
|
316
319
|
|
317
320
|
|
@@ -495,7 +498,7 @@ class Services(object):
|
|
495
498
|
res_file = 'f' in string
|
496
499
|
|
497
500
|
parsed = cls(blob=res_blob, queue=res_queue, fileshare=res_file)
|
498
|
-
parsed._str = string
|
501
|
+
parsed._str = string
|
499
502
|
return parsed
|
500
503
|
|
501
504
|
|
@@ -35,11 +35,6 @@ from .authentication import AzureSigningError, StorageHttpChallenge
|
|
35
35
|
from .constants import DEFAULT_OAUTH_SCOPE
|
36
36
|
from .models import LocationMode
|
37
37
|
|
38
|
-
try:
|
39
|
-
_unicode_type = unicode # type: ignore
|
40
|
-
except NameError:
|
41
|
-
_unicode_type = str
|
42
|
-
|
43
38
|
if TYPE_CHECKING:
|
44
39
|
from azure.core.credentials import TokenCredential
|
45
40
|
from azure.core.pipeline.transport import ( # pylint: disable=non-abstract-transport-import
|
@@ -52,7 +47,7 @@ _LOGGER = logging.getLogger(__name__)
|
|
52
47
|
|
53
48
|
|
54
49
|
def encode_base64(data):
|
55
|
-
if isinstance(data,
|
50
|
+
if isinstance(data, str):
|
56
51
|
data = data.encode('utf-8')
|
57
52
|
encoded = base64.b64encode(data)
|
58
53
|
return encoded.decode('utf-8')
|
@@ -77,7 +72,7 @@ def retry_hook(settings, **kwargs):
|
|
77
72
|
# respect the Retry-After header, whether this header is present, and
|
78
73
|
# whether the returned status code is on the list of status codes to
|
79
74
|
# be retried upon on the presence of the aforementioned header)
|
80
|
-
def is_retry(response, mode):
|
75
|
+
def is_retry(response, mode):
|
81
76
|
status = response.http_response.status_code
|
82
77
|
if 300 <= status < 500:
|
83
78
|
# An exception occurred, but in most cases it was expected. Examples could
|
@@ -95,10 +90,14 @@ def is_retry(response, mode): # pylint: disable=too-many-return-statements
|
|
95
90
|
if status in [501, 505]:
|
96
91
|
return False
|
97
92
|
return True
|
93
|
+
return False
|
94
|
+
|
95
|
+
|
96
|
+
def is_checksum_retry(response):
|
98
97
|
# retry if invalid content md5
|
99
98
|
if response.context.get('validate_content', False) and response.http_response.headers.get('content-md5'):
|
100
99
|
computed_md5 = response.http_request.headers.get('content-md5', None) or \
|
101
|
-
|
100
|
+
encode_base64(StorageContentValidation.get_content_md5(response.http_response.body()))
|
102
101
|
if response.http_response.headers['content-md5'] != computed_md5:
|
103
102
|
return True
|
104
103
|
return False
|
@@ -268,7 +267,7 @@ class StorageLoggingPolicy(NetworkTraceLoggingPolicy):
|
|
268
267
|
|
269
268
|
class StorageRequestHook(SansIOHTTPPolicy):
|
270
269
|
|
271
|
-
def __init__(self, **kwargs):
|
270
|
+
def __init__(self, **kwargs):
|
272
271
|
self._request_callback = kwargs.get('raw_request_hook')
|
273
272
|
super(StorageRequestHook, self).__init__()
|
274
273
|
|
@@ -280,7 +279,7 @@ class StorageRequestHook(SansIOHTTPPolicy):
|
|
280
279
|
|
281
280
|
class StorageResponseHook(HTTPPolicy):
|
282
281
|
|
283
|
-
def __init__(self, **kwargs):
|
282
|
+
def __init__(self, **kwargs):
|
284
283
|
self._response_callback = kwargs.get('raw_response_hook')
|
285
284
|
super(StorageResponseHook, self).__init__()
|
286
285
|
|
@@ -301,7 +300,7 @@ class StorageResponseHook(HTTPPolicy):
|
|
301
300
|
|
302
301
|
response = self.next.send(request)
|
303
302
|
|
304
|
-
will_retry = is_retry(response, request.context.options.get('mode'))
|
303
|
+
will_retry = is_retry(response, request.context.options.get('mode')) or is_checksum_retry(response)
|
305
304
|
# Auth error could come from Bearer challenge, in which case this request will be made again
|
306
305
|
is_auth_error = response.http_response.status_code == 401
|
307
306
|
should_update_counts = not (will_retry or is_auth_error)
|
@@ -451,7 +450,7 @@ class StorageRetryPolicy(HTTPPolicy):
|
|
451
450
|
""" Formula for computing the current backoff.
|
452
451
|
Should be calculated by child class.
|
453
452
|
|
454
|
-
:param Dict[str, Any]
|
453
|
+
:param Dict[str, Any] settings: The configurable values pertaining to the backoff time.
|
455
454
|
:returns: The backoff time.
|
456
455
|
:rtype: float
|
457
456
|
"""
|
@@ -471,12 +470,11 @@ class StorageRetryPolicy(HTTPPolicy):
|
|
471
470
|
) -> bool:
|
472
471
|
"""Increment the retry counters.
|
473
472
|
|
474
|
-
:param Dict[str, Any]
|
473
|
+
:param Dict[str, Any] settings: The configurable values pertaining to the increment operation.
|
475
474
|
:param PipelineRequest request: A pipeline request object.
|
476
475
|
:param Optional[PipelineResponse] response: A pipeline response object.
|
477
|
-
:param error: An error encountered during the request, or
|
476
|
+
:param Optional[AzureError] error: An error encountered during the request, or
|
478
477
|
None if the response was received successfully.
|
479
|
-
:type error: Optional[AzureError]
|
480
478
|
:returns: Whether the retry attempts are exhausted.
|
481
479
|
:rtype: bool
|
482
480
|
"""
|
@@ -527,7 +525,7 @@ class StorageRetryPolicy(HTTPPolicy):
|
|
527
525
|
while retries_remaining:
|
528
526
|
try:
|
529
527
|
response = self.next.send(request)
|
530
|
-
if is_retry(response, retry_settings['mode']):
|
528
|
+
if is_retry(response, retry_settings['mode']) or is_checksum_retry(response):
|
531
529
|
retries_remaining = self.increment(
|
532
530
|
retry_settings,
|
533
531
|
request=request.http_request,
|