azure-storage-blob 12.21.0__py3-none-any.whl → 12.22.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/__init__.py +19 -18
- azure/storage/blob/_blob_client.py +417 -1507
- azure/storage/blob/_blob_client_helpers.py +1242 -0
- azure/storage/blob/_blob_service_client.py +82 -101
- azure/storage/blob/_blob_service_client_helpers.py +27 -0
- azure/storage/blob/_container_client.py +147 -356
- azure/storage/blob/_container_client_helpers.py +261 -0
- azure/storage/blob/_deserialize.py +68 -44
- azure/storage/blob/_download.py +114 -90
- azure/storage/blob/_encryption.py +14 -7
- azure/storage/blob/_lease.py +47 -58
- azure/storage/blob/_list_blobs_helper.py +129 -135
- azure/storage/blob/_models.py +479 -276
- azure/storage/blob/_quick_query_helper.py +30 -31
- azure/storage/blob/_serialize.py +38 -56
- azure/storage/blob/_shared/avro/datafile.py +1 -1
- azure/storage/blob/_shared/avro/datafile_async.py +1 -1
- azure/storage/blob/_shared/base_client.py +1 -1
- azure/storage/blob/_shared/base_client_async.py +1 -1
- azure/storage/blob/_shared/policies.py +8 -6
- azure/storage/blob/_shared/policies_async.py +3 -1
- azure/storage/blob/_shared/response_handlers.py +6 -2
- azure/storage/blob/_shared/shared_access_signature.py +2 -2
- azure/storage/blob/_shared/uploads.py +1 -1
- azure/storage/blob/_shared/uploads_async.py +1 -1
- azure/storage/blob/_shared_access_signature.py +70 -53
- azure/storage/blob/_upload_helpers.py +75 -68
- azure/storage/blob/_version.py +1 -1
- azure/storage/blob/aio/__init__.py +19 -11
- azure/storage/blob/aio/_blob_client_async.py +505 -255
- azure/storage/blob/aio/_blob_service_client_async.py +138 -87
- azure/storage/blob/aio/_container_client_async.py +260 -120
- azure/storage/blob/aio/_download_async.py +104 -87
- azure/storage/blob/aio/_lease_async.py +56 -55
- azure/storage/blob/aio/_list_blobs_helper.py +94 -96
- azure/storage/blob/aio/_models.py +60 -38
- azure/storage/blob/aio/_upload_helpers.py +75 -66
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/METADATA +1 -1
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/RECORD +42 -39
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/LICENSE +0 -0
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/WHEEL +0 -0
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/top_level.txt +0 -0
@@ -7,33 +7,30 @@
|
|
7
7
|
|
8
8
|
import functools
|
9
9
|
import warnings
|
10
|
+
from datetime import datetime
|
10
11
|
from typing import (
|
11
|
-
Any, AnyStr, Dict, List, IO, Iterable, Iterator, Optional, overload, Union,
|
12
|
+
Any, AnyStr, cast, Dict, List, IO, Iterable, Iterator, Optional, overload, Union,
|
12
13
|
TYPE_CHECKING
|
13
14
|
)
|
14
|
-
from urllib.parse import
|
15
|
-
|
15
|
+
from urllib.parse import unquote, urlparse
|
16
16
|
from typing_extensions import Self
|
17
17
|
|
18
|
-
from azure.core import MatchConditions
|
19
18
|
from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
|
20
19
|
from azure.core.paging import ItemPaged
|
21
20
|
from azure.core.pipeline import Pipeline
|
22
|
-
from azure.core.pipeline.transport import HttpRequest
|
23
21
|
from azure.core.tracing.decorator import distributed_trace
|
24
|
-
from ._shared.base_client import StorageAccountHostsMixin, TransportWrapper, parse_connection_str, parse_query
|
25
|
-
from ._shared.request_handlers import add_metadata_headers, serialize_iso
|
26
|
-
from ._shared.response_handlers import (
|
27
|
-
process_storage_error,
|
28
|
-
return_response_headers,
|
29
|
-
return_headers_and_deserialized
|
30
|
-
)
|
31
|
-
from ._generated import AzureBlobStorage
|
32
|
-
from ._generated.models import SignedIdentifier
|
33
22
|
from ._blob_client import BlobClient
|
23
|
+
from ._container_client_helpers import (
|
24
|
+
_format_url,
|
25
|
+
_generate_delete_blobs_options,
|
26
|
+
_generate_set_tiers_options,
|
27
|
+
_parse_url
|
28
|
+
)
|
34
29
|
from ._deserialize import deserialize_container_properties
|
35
30
|
from ._download import StorageStreamDownloader
|
36
31
|
from ._encryption import StorageEncryptionMixin
|
32
|
+
from ._generated import AzureBlobStorage
|
33
|
+
from ._generated.models import SignedIdentifier
|
37
34
|
from ._lease import BlobLeaseClient
|
38
35
|
from ._list_blobs_helper import (
|
39
36
|
BlobNamesPaged,
|
@@ -43,36 +40,30 @@ from ._list_blobs_helper import (
|
|
43
40
|
IgnoreListBlobsDeserializer
|
44
41
|
)
|
45
42
|
from ._models import (
|
46
|
-
ContainerProperties,
|
47
43
|
BlobProperties,
|
48
44
|
BlobType,
|
45
|
+
ContainerProperties,
|
49
46
|
FilteredBlob
|
50
47
|
)
|
51
|
-
from ._serialize import
|
48
|
+
from ._serialize import get_access_conditions, get_api_version, get_container_cpk_scope_info, get_modify_conditions
|
49
|
+
from ._shared.base_client import parse_connection_str, StorageAccountHostsMixin, TransportWrapper
|
50
|
+
from ._shared.request_handlers import add_metadata_headers, serialize_iso
|
51
|
+
from ._shared.response_handlers import (
|
52
|
+
process_storage_error,
|
53
|
+
return_headers_and_deserialized,
|
54
|
+
return_response_headers
|
55
|
+
)
|
52
56
|
|
53
57
|
if TYPE_CHECKING:
|
54
58
|
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential
|
55
59
|
from azure.core.pipeline.transport import HttpResponse # pylint: disable=C4756
|
56
|
-
from
|
57
|
-
from ._models import (
|
58
|
-
PublicAccess,
|
60
|
+
from azure.storage.blob import BlobServiceClient
|
61
|
+
from ._models import (
|
59
62
|
AccessPolicy,
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def _get_blob_name(blob):
|
65
|
-
"""Return the blob name.
|
66
|
-
|
67
|
-
:param blob: A blob string or BlobProperties
|
68
|
-
:type blob: str or BlobProperties
|
69
|
-
:returns: The name of the blob.
|
70
|
-
:rtype: str
|
71
|
-
"""
|
72
|
-
try:
|
73
|
-
return blob.get('name')
|
74
|
-
except AttributeError:
|
75
|
-
return blob
|
63
|
+
PremiumPageBlobTier,
|
64
|
+
PublicAccess,
|
65
|
+
StandardBlobTier
|
66
|
+
)
|
76
67
|
|
77
68
|
|
78
69
|
class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # pylint: disable=too-many-public-methods
|
@@ -143,23 +134,13 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
143
134
|
:caption: Creating the container client directly.
|
144
135
|
"""
|
145
136
|
def __init__(
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
if not account_url.lower().startswith('http'):
|
153
|
-
account_url = "https://" + account_url
|
154
|
-
except AttributeError as exc:
|
155
|
-
raise ValueError("Container URL must be a string.") from exc
|
156
|
-
parsed_url = urlparse(account_url.rstrip('/'))
|
157
|
-
if not container_name:
|
158
|
-
raise ValueError("Please specify a container name.")
|
159
|
-
if not parsed_url.netloc:
|
160
|
-
raise ValueError(f"Invalid URL: {account_url}")
|
137
|
+
self, account_url: str,
|
138
|
+
container_name: str,
|
139
|
+
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long
|
140
|
+
**kwargs: Any
|
141
|
+
) -> None:
|
142
|
+
parsed_url, sas_token = _parse_url(account_url=account_url, container_name=container_name)
|
161
143
|
|
162
|
-
_, sas_token = parse_query(parsed_url.query)
|
163
144
|
self.container_name = container_name
|
164
145
|
# This parameter is used for the hierarchy traversal. Give precedence to credential.
|
165
146
|
self._raw_credential = credential if credential else sas_token
|
@@ -169,23 +150,25 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
169
150
|
self._client = self._build_generated_client()
|
170
151
|
self._configure_encryption(kwargs)
|
171
152
|
|
172
|
-
def _build_generated_client(self):
|
153
|
+
def _build_generated_client(self) -> AzureBlobStorage:
|
173
154
|
client = AzureBlobStorage(self.url, base_url=self.url, pipeline=self._pipeline)
|
174
|
-
client._config.version = self._api_version # pylint: disable=protected-access
|
155
|
+
client._config.version = self._api_version # type: ignore [assignment] # pylint: disable=protected-access
|
175
156
|
return client
|
176
157
|
|
177
158
|
def _format_url(self, hostname):
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
159
|
+
return _format_url(
|
160
|
+
container_name=self.container_name,
|
161
|
+
hostname=hostname,
|
162
|
+
scheme=self.scheme,
|
163
|
+
query_str=self._query_str
|
164
|
+
)
|
182
165
|
|
183
166
|
@classmethod
|
184
167
|
def from_container_url(
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
168
|
+
cls, container_url: str,
|
169
|
+
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long
|
170
|
+
**kwargs: Any
|
171
|
+
) -> Self:
|
189
172
|
"""Create ContainerClient from a container url.
|
190
173
|
|
191
174
|
:param str container_url:
|
@@ -234,11 +217,11 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
234
217
|
|
235
218
|
@classmethod
|
236
219
|
def from_connection_string(
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
220
|
+
cls, conn_str: str,
|
221
|
+
container_name: str,
|
222
|
+
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "TokenCredential"]] = None, # pylint: disable=line-too-long
|
223
|
+
**kwargs: Any
|
224
|
+
) -> Self:
|
242
225
|
"""Create ContainerClient from a Connection String.
|
243
226
|
|
244
227
|
:param str conn_str:
|
@@ -282,8 +265,11 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
282
265
|
account_url, container_name=container_name, credential=credential, **kwargs)
|
283
266
|
|
284
267
|
@distributed_trace
|
285
|
-
def create_container(
|
286
|
-
|
268
|
+
def create_container(
|
269
|
+
self, metadata: Optional[Dict[str, str]] = None,
|
270
|
+
public_access: Optional[Union["PublicAccess", str]] = None,
|
271
|
+
**kwargs: Any
|
272
|
+
) -> Dict[str, Union[str, "datetime"]]:
|
287
273
|
"""
|
288
274
|
Creates a new container under the specified account. If the container
|
289
275
|
with the same name already exists, the operation fails.
|
@@ -335,8 +321,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
335
321
|
process_storage_error(error)
|
336
322
|
|
337
323
|
@distributed_trace
|
338
|
-
def _rename_container(self, new_name, **kwargs):
|
339
|
-
# type: (str, **Any) -> ContainerClient
|
324
|
+
def _rename_container(self, new_name: str, **kwargs: Any) -> "ContainerClient":
|
340
325
|
"""Renames a container.
|
341
326
|
|
342
327
|
Operation is successful only if the source container exists.
|
@@ -374,9 +359,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
374
359
|
process_storage_error(error)
|
375
360
|
|
376
361
|
@distributed_trace
|
377
|
-
def delete_container(
|
378
|
-
self, **kwargs):
|
379
|
-
# type: (Any) -> None
|
362
|
+
def delete_container(self, **kwargs: Any) -> None:
|
380
363
|
"""
|
381
364
|
Marks the specified container for deletion. The container and any blobs
|
382
365
|
contained within it are later deleted during garbage collection.
|
@@ -435,10 +418,10 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
435
418
|
|
436
419
|
@distributed_trace
|
437
420
|
def acquire_lease(
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
421
|
+
self, lease_duration: int =-1,
|
422
|
+
lease_id: Optional[str] = None,
|
423
|
+
**kwargs: Any
|
424
|
+
) -> BlobLeaseClient:
|
442
425
|
"""
|
443
426
|
Requests a new lease. If the container does not have an active lease,
|
444
427
|
the Blob service creates a lease on the container and returns a new
|
@@ -494,8 +477,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
494
477
|
return lease
|
495
478
|
|
496
479
|
@distributed_trace
|
497
|
-
def get_account_information(self, **kwargs):
|
498
|
-
# type: (**Any) -> Dict[str, str]
|
480
|
+
def get_account_information(self, **kwargs: Any) -> Dict[str, str]:
|
499
481
|
"""Gets information related to the storage account.
|
500
482
|
|
501
483
|
The information can also be retrieved if the user has a SAS to a container or blob.
|
@@ -510,8 +492,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
510
492
|
process_storage_error(error)
|
511
493
|
|
512
494
|
@distributed_trace
|
513
|
-
def get_container_properties(self, **kwargs):
|
514
|
-
# type: (Any) -> ContainerProperties
|
495
|
+
def get_container_properties(self, **kwargs: Any) -> ContainerProperties:
|
515
496
|
"""Returns all user-defined metadata and system properties for the specified
|
516
497
|
container. The data returned does not include the container's list of blobs.
|
517
498
|
|
@@ -552,8 +533,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
552
533
|
return response # type: ignore
|
553
534
|
|
554
535
|
@distributed_trace
|
555
|
-
def exists(self, **kwargs):
|
556
|
-
# type: (**Any) -> bool
|
536
|
+
def exists(self, **kwargs: Any) -> bool:
|
557
537
|
"""
|
558
538
|
Returns True if a container exists and returns False otherwise.
|
559
539
|
|
@@ -576,11 +556,10 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
576
556
|
return False
|
577
557
|
|
578
558
|
@distributed_trace
|
579
|
-
def set_container_metadata(
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
# type: (...) -> Dict[str, Union[str, datetime]]
|
559
|
+
def set_container_metadata(
|
560
|
+
self, metadata: Optional[Dict[str, str]] = None,
|
561
|
+
**kwargs: Any
|
562
|
+
) -> Dict[str, Union[str, "datetime"]]:
|
584
563
|
"""Sets one or more user-defined name-value pairs for the specified
|
585
564
|
container. Each call to this operation replaces all existing metadata
|
586
565
|
attached to the container. To remove all metadata from the container,
|
@@ -645,8 +624,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
645
624
|
process_storage_error(error)
|
646
625
|
|
647
626
|
@distributed_trace
|
648
|
-
def _get_blob_service_client(self): # pylint: disable=client-method-missing-kwargs
|
649
|
-
# type: (...) -> BlobServiceClient
|
627
|
+
def _get_blob_service_client(self) -> "BlobServiceClient": # pylint: disable=client-method-missing-kwargs
|
650
628
|
"""Get a client to interact with the container's parent service account.
|
651
629
|
|
652
630
|
Defaults to current container's credentials.
|
@@ -679,8 +657,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
679
657
|
key_resolver_function=self.key_resolver_function, _pipeline=_pipeline)
|
680
658
|
|
681
659
|
@distributed_trace
|
682
|
-
def get_container_access_policy(self, **kwargs):
|
683
|
-
# type: (Any) -> Dict[str, Any]
|
660
|
+
def get_container_access_policy(self, **kwargs: Any) -> Dict[str, Any]:
|
684
661
|
"""Gets the permissions for the specified container.
|
685
662
|
The permissions indicate whether container data may be accessed publicly.
|
686
663
|
|
@@ -724,10 +701,10 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
724
701
|
|
725
702
|
@distributed_trace
|
726
703
|
def set_container_access_policy(
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
704
|
+
self, signed_identifiers: Dict[str, "AccessPolicy"],
|
705
|
+
public_access: Optional[Union[str, "PublicAccess"]] = None,
|
706
|
+
**kwargs: Any
|
707
|
+
) -> Dict[str, Union[str, datetime]]:
|
731
708
|
"""Sets the permissions for the specified container or stored access
|
732
709
|
policies that may be used with Shared Access Signatures. The permissions
|
733
710
|
indicate whether blobs in a container may be accessed publicly.
|
@@ -789,14 +766,14 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
789
766
|
access_conditions = get_access_conditions(lease)
|
790
767
|
timeout = kwargs.pop('timeout', None)
|
791
768
|
try:
|
792
|
-
return self._client.container.set_access_policy(
|
769
|
+
return cast(Dict[str, Union[str, datetime]], self._client.container.set_access_policy(
|
793
770
|
container_acl=signed_identifiers or None,
|
794
771
|
timeout=timeout,
|
795
772
|
access=public_access,
|
796
773
|
lease_access_conditions=access_conditions,
|
797
774
|
modified_access_conditions=mod_conditions,
|
798
775
|
cls=return_response_headers,
|
799
|
-
**kwargs)
|
776
|
+
**kwargs))
|
800
777
|
except HttpResponseError as error:
|
801
778
|
process_storage_error(error)
|
802
779
|
|
@@ -851,7 +828,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
851
828
|
timeout=timeout,
|
852
829
|
**kwargs)
|
853
830
|
return ItemPaged(
|
854
|
-
command, prefix=name_starts_with, results_per_page=results_per_page,
|
831
|
+
command, prefix=name_starts_with, results_per_page=results_per_page, container=self.container_name,
|
855
832
|
page_iterator_class=BlobPropertiesPaged)
|
856
833
|
|
857
834
|
@distributed_trace
|
@@ -897,6 +874,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
897
874
|
command,
|
898
875
|
prefix=name_starts_with,
|
899
876
|
results_per_page=results_per_page,
|
877
|
+
container=self.container_name,
|
900
878
|
page_iterator_class=BlobNamesPaged)
|
901
879
|
|
902
880
|
@distributed_trace
|
@@ -905,7 +883,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
905
883
|
include: Optional[Union[List[str], str]] = None,
|
906
884
|
delimiter: str = "/",
|
907
885
|
**kwargs: Any
|
908
|
-
|
886
|
+
) -> ItemPaged[BlobProperties]:
|
909
887
|
"""Returns a generator to list the blobs under the specified container.
|
910
888
|
The generator will lazily follow the continuation tokens returned by
|
911
889
|
the service. This operation will list blobs in accordance with a hierarchy,
|
@@ -952,14 +930,14 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
952
930
|
command,
|
953
931
|
prefix=name_starts_with,
|
954
932
|
results_per_page=results_per_page,
|
933
|
+
container=self.container_name,
|
955
934
|
delimiter=delimiter)
|
956
935
|
|
957
936
|
@distributed_trace
|
958
937
|
def find_blobs_by_tags(
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
# type: (...) -> ItemPaged[FilteredBlob]
|
938
|
+
self, filter_expression: str,
|
939
|
+
**kwargs: Any
|
940
|
+
) -> ItemPaged[FilteredBlob]:
|
963
941
|
"""Returns a generator to list the blobs under the specified container whose tags
|
964
942
|
match the given search expression.
|
965
943
|
The generator will lazily follow the continuation tokens returned by
|
@@ -987,18 +965,18 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
987
965
|
where=filter_expression,
|
988
966
|
**kwargs)
|
989
967
|
return ItemPaged(
|
990
|
-
command, results_per_page=results_per_page,
|
968
|
+
command, results_per_page=results_per_page, container=self.container_name,
|
991
969
|
page_iterator_class=FilteredBlobPaged)
|
992
970
|
|
993
971
|
@distributed_trace
|
994
972
|
def upload_blob(
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
973
|
+
self, name: str,
|
974
|
+
data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]],
|
975
|
+
blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB,
|
976
|
+
length: Optional[int] = None,
|
977
|
+
metadata: Optional[Dict[str, str]] = None,
|
978
|
+
**kwargs
|
979
|
+
) -> BlobClient:
|
1002
980
|
"""Creates a new blob from a data source with automatic chunking.
|
1003
981
|
|
1004
982
|
:param str name: The blob with which to interact.
|
@@ -1135,11 +1113,10 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1135
1113
|
|
1136
1114
|
@distributed_trace
|
1137
1115
|
def delete_blob(
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
# type: (...) -> None
|
1116
|
+
self, blob: str,
|
1117
|
+
delete_snapshots: Optional[str] = None,
|
1118
|
+
**kwargs: Any
|
1119
|
+
) -> None:
|
1143
1120
|
"""Marks the specified blob or snapshot for deletion.
|
1144
1121
|
|
1145
1122
|
The blob is later deleted during garbage collection.
|
@@ -1217,35 +1194,35 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1217
1194
|
|
1218
1195
|
@overload
|
1219
1196
|
def download_blob(
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1197
|
+
self, blob: str,
|
1198
|
+
offset: Optional[int] = None,
|
1199
|
+
length: Optional[int] = None,
|
1200
|
+
*,
|
1201
|
+
encoding: str,
|
1202
|
+
**kwargs: Any
|
1226
1203
|
) -> StorageStreamDownloader[str]:
|
1227
1204
|
...
|
1228
1205
|
|
1229
1206
|
@overload
|
1230
1207
|
def download_blob(
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1208
|
+
self, blob: str,
|
1209
|
+
offset: Optional[int] = None,
|
1210
|
+
length: Optional[int] = None,
|
1211
|
+
*,
|
1212
|
+
encoding: None = None,
|
1213
|
+
**kwargs: Any
|
1237
1214
|
) -> StorageStreamDownloader[bytes]:
|
1238
1215
|
...
|
1239
1216
|
|
1240
1217
|
@distributed_trace
|
1241
1218
|
def download_blob(
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
) -> StorageStreamDownloader:
|
1219
|
+
self, blob: str,
|
1220
|
+
offset: Optional[int] = None,
|
1221
|
+
length: Optional[int] = None,
|
1222
|
+
*,
|
1223
|
+
encoding: Union[str, None] = None,
|
1224
|
+
**kwargs: Any
|
1225
|
+
) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]:
|
1249
1226
|
"""Downloads a blob to the StorageStreamDownloader. The readall() method must
|
1250
1227
|
be used to read all the content or readinto() must be used to download the blob into
|
1251
1228
|
a stream. Using chunks() returns an iterator which allows the user to iterate over the content in chunks.
|
@@ -1342,131 +1319,11 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1342
1319
|
encoding=encoding,
|
1343
1320
|
**kwargs)
|
1344
1321
|
|
1345
|
-
# This code is a copy from _generated.
|
1346
|
-
# Once Autorest is able to provide request preparation this code should be removed.
|
1347
|
-
def _generate_delete_blobs_subrequest_options(
|
1348
|
-
self, snapshot=None,
|
1349
|
-
version_id=None,
|
1350
|
-
delete_snapshots=None,
|
1351
|
-
lease_access_conditions=None,
|
1352
|
-
modified_access_conditions=None,
|
1353
|
-
**kwargs
|
1354
|
-
):
|
1355
|
-
lease_id = None
|
1356
|
-
if lease_access_conditions is not None:
|
1357
|
-
lease_id = lease_access_conditions.lease_id
|
1358
|
-
if_modified_since = None
|
1359
|
-
if modified_access_conditions is not None:
|
1360
|
-
if_modified_since = modified_access_conditions.if_modified_since
|
1361
|
-
if_unmodified_since = None
|
1362
|
-
if modified_access_conditions is not None:
|
1363
|
-
if_unmodified_since = modified_access_conditions.if_unmodified_since
|
1364
|
-
if_match = None
|
1365
|
-
if modified_access_conditions is not None:
|
1366
|
-
if_match = modified_access_conditions.if_match
|
1367
|
-
if_none_match = None
|
1368
|
-
if modified_access_conditions is not None:
|
1369
|
-
if_none_match = modified_access_conditions.if_none_match
|
1370
|
-
if_tags = None
|
1371
|
-
if modified_access_conditions is not None:
|
1372
|
-
if_tags = modified_access_conditions.if_tags
|
1373
|
-
|
1374
|
-
# Construct parameters
|
1375
|
-
timeout = kwargs.pop('timeout', None)
|
1376
|
-
query_parameters = {}
|
1377
|
-
if snapshot is not None:
|
1378
|
-
query_parameters['snapshot'] = self._client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
|
1379
|
-
if version_id is not None:
|
1380
|
-
query_parameters['versionid'] = self._client._serialize.query("version_id", version_id, 'str') # pylint: disable=protected-access
|
1381
|
-
if timeout is not None:
|
1382
|
-
query_parameters['timeout'] = self._client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
|
1383
|
-
|
1384
|
-
# Construct headers
|
1385
|
-
header_parameters = {}
|
1386
|
-
if delete_snapshots is not None:
|
1387
|
-
header_parameters['x-ms-delete-snapshots'] = self._client._serialize.header( # pylint: disable=protected-access
|
1388
|
-
"delete_snapshots", delete_snapshots, 'DeleteSnapshotsOptionType')
|
1389
|
-
if lease_id is not None:
|
1390
|
-
header_parameters['x-ms-lease-id'] = self._client._serialize.header( # pylint: disable=protected-access
|
1391
|
-
"lease_id", lease_id, 'str')
|
1392
|
-
if if_modified_since is not None:
|
1393
|
-
header_parameters['If-Modified-Since'] = self._client._serialize.header( # pylint: disable=protected-access
|
1394
|
-
"if_modified_since", if_modified_since, 'rfc-1123')
|
1395
|
-
if if_unmodified_since is not None:
|
1396
|
-
header_parameters['If-Unmodified-Since'] = self._client._serialize.header( # pylint: disable=protected-access
|
1397
|
-
"if_unmodified_since", if_unmodified_since, 'rfc-1123')
|
1398
|
-
if if_match is not None:
|
1399
|
-
header_parameters['If-Match'] = self._client._serialize.header( # pylint: disable=protected-access
|
1400
|
-
"if_match", if_match, 'str')
|
1401
|
-
if if_none_match is not None:
|
1402
|
-
header_parameters['If-None-Match'] = self._client._serialize.header( # pylint: disable=protected-access
|
1403
|
-
"if_none_match", if_none_match, 'str')
|
1404
|
-
if if_tags is not None:
|
1405
|
-
header_parameters['x-ms-if-tags'] = self._client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
|
1406
|
-
|
1407
|
-
return query_parameters, header_parameters
|
1408
|
-
|
1409
|
-
def _generate_delete_blobs_options(
|
1410
|
-
self, *blobs: Union[str, Dict[str, Any], BlobProperties],
|
1411
|
-
**kwargs: Any
|
1412
|
-
):
|
1413
|
-
timeout = kwargs.pop('timeout', None)
|
1414
|
-
raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
|
1415
|
-
delete_snapshots = kwargs.pop('delete_snapshots', None)
|
1416
|
-
if_modified_since = kwargs.pop('if_modified_since', None)
|
1417
|
-
if_unmodified_since = kwargs.pop('if_unmodified_since', None)
|
1418
|
-
if_tags_match_condition = kwargs.pop('if_tags_match_condition', None)
|
1419
|
-
kwargs.update({'raise_on_any_failure': raise_on_any_failure,
|
1420
|
-
'sas': self._query_str.replace('?', '&'),
|
1421
|
-
'timeout': '&timeout=' + str(timeout) if timeout else "",
|
1422
|
-
'path': self.container_name,
|
1423
|
-
'restype': 'restype=container&'
|
1424
|
-
})
|
1425
|
-
|
1426
|
-
reqs = []
|
1427
|
-
for blob in blobs:
|
1428
|
-
blob_name = _get_blob_name(blob)
|
1429
|
-
container_name = self.container_name
|
1430
|
-
|
1431
|
-
try:
|
1432
|
-
options = BlobClient._generic_delete_blob_options( # pylint: disable=protected-access
|
1433
|
-
snapshot=blob.get('snapshot'),
|
1434
|
-
version_id=blob.get('version_id'),
|
1435
|
-
delete_snapshots=delete_snapshots or blob.get('delete_snapshots'),
|
1436
|
-
lease=blob.get('lease_id'),
|
1437
|
-
if_modified_since=if_modified_since or blob.get('if_modified_since'),
|
1438
|
-
if_unmodified_since=if_unmodified_since or blob.get('if_unmodified_since'),
|
1439
|
-
etag=blob.get('etag'),
|
1440
|
-
if_tags_match_condition=if_tags_match_condition or blob.get('if_tags_match_condition'),
|
1441
|
-
match_condition=blob.get('match_condition') or MatchConditions.IfNotModified if blob.get('etag')
|
1442
|
-
else None,
|
1443
|
-
timeout=blob.get('timeout'),
|
1444
|
-
)
|
1445
|
-
except AttributeError:
|
1446
|
-
options = BlobClient._generic_delete_blob_options( # pylint: disable=protected-access
|
1447
|
-
delete_snapshots=delete_snapshots,
|
1448
|
-
if_modified_since=if_modified_since,
|
1449
|
-
if_unmodified_since=if_unmodified_since,
|
1450
|
-
if_tags_match_condition=if_tags_match_condition
|
1451
|
-
)
|
1452
|
-
|
1453
|
-
query_parameters, header_parameters = self._generate_delete_blobs_subrequest_options(**options)
|
1454
|
-
|
1455
|
-
req = HttpRequest(
|
1456
|
-
"DELETE",
|
1457
|
-
f"/{quote(container_name)}/{quote(blob_name, safe='/~')}{self._query_str}",
|
1458
|
-
headers=header_parameters
|
1459
|
-
)
|
1460
|
-
req.format_parameters(query_parameters)
|
1461
|
-
reqs.append(req)
|
1462
|
-
|
1463
|
-
return reqs, kwargs
|
1464
|
-
|
1465
1322
|
@distributed_trace
|
1466
1323
|
def delete_blobs( # pylint: disable=delete-operation-wrong-return-type
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1324
|
+
self, *blobs: Union[str, Dict[str, Any], BlobProperties],
|
1325
|
+
**kwargs: Any
|
1326
|
+
) -> Iterator["HttpResponse"]:
|
1470
1327
|
"""Marks the specified blobs or snapshots for deletion.
|
1471
1328
|
|
1472
1329
|
The blobs are later deleted during garbage collection.
|
@@ -1509,7 +1366,7 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1509
1366
|
timeout for subrequest:
|
1510
1367
|
key: 'timeout', value type: int
|
1511
1368
|
|
1512
|
-
:type blobs: str
|
1369
|
+
:type blobs: Union[str, Dict[str, Any], BlobProperties]
|
1513
1370
|
:keyword str delete_snapshots:
|
1514
1371
|
Required if a blob has associated snapshots. Values include:
|
1515
1372
|
- "only": Deletes only the blobs snapshots.
|
@@ -1556,99 +1413,19 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1556
1413
|
if len(blobs) == 0:
|
1557
1414
|
return iter([])
|
1558
1415
|
|
1559
|
-
reqs, options =
|
1416
|
+
reqs, options = _generate_delete_blobs_options(
|
1417
|
+
self._query_str,
|
1418
|
+
self.container_name,
|
1419
|
+
self._client,
|
1420
|
+
*blobs,
|
1421
|
+
**kwargs
|
1422
|
+
)
|
1560
1423
|
|
1561
1424
|
return self._batch_send(*reqs, **options)
|
1562
1425
|
|
1563
|
-
# This code is a copy from _generated.
|
1564
|
-
# Once Autorest is able to provide request preparation this code should be removed.
|
1565
|
-
def _generate_set_tiers_subrequest_options(
|
1566
|
-
self, tier, snapshot=None, version_id=None, rehydrate_priority=None, lease_access_conditions=None, **kwargs
|
1567
|
-
):
|
1568
|
-
if not tier:
|
1569
|
-
raise ValueError("A blob tier must be specified")
|
1570
|
-
if snapshot and version_id:
|
1571
|
-
raise ValueError("Snapshot and version_id cannot be set at the same time")
|
1572
|
-
if_tags = kwargs.pop('if_tags', None)
|
1573
|
-
|
1574
|
-
lease_id = None
|
1575
|
-
if lease_access_conditions is not None:
|
1576
|
-
lease_id = lease_access_conditions.lease_id
|
1577
|
-
|
1578
|
-
comp = "tier"
|
1579
|
-
timeout = kwargs.pop('timeout', None)
|
1580
|
-
# Construct parameters
|
1581
|
-
query_parameters = {}
|
1582
|
-
if snapshot is not None:
|
1583
|
-
query_parameters['snapshot'] = self._client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
|
1584
|
-
if version_id is not None:
|
1585
|
-
query_parameters['versionid'] = self._client._serialize.query("version_id", version_id, 'str') # pylint: disable=protected-access
|
1586
|
-
if timeout is not None:
|
1587
|
-
query_parameters['timeout'] = self._client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
|
1588
|
-
query_parameters['comp'] = self._client._serialize.query("comp", comp, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
|
1589
|
-
|
1590
|
-
# Construct headers
|
1591
|
-
header_parameters = {}
|
1592
|
-
header_parameters['x-ms-access-tier'] = self._client._serialize.header("tier", tier, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
|
1593
|
-
if rehydrate_priority is not None:
|
1594
|
-
header_parameters['x-ms-rehydrate-priority'] = self._client._serialize.header( # pylint: disable=protected-access
|
1595
|
-
"rehydrate_priority", rehydrate_priority, 'str')
|
1596
|
-
if lease_id is not None:
|
1597
|
-
header_parameters['x-ms-lease-id'] = self._client._serialize.header("lease_id", lease_id, 'str') # pylint: disable=protected-access
|
1598
|
-
if if_tags is not None:
|
1599
|
-
header_parameters['x-ms-if-tags'] = self._client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
|
1600
|
-
|
1601
|
-
return query_parameters, header_parameters
|
1602
|
-
|
1603
|
-
def _generate_set_tiers_options(
|
1604
|
-
self, blob_tier: Optional[Union[str, 'StandardBlobTier', 'PremiumPageBlobTier']],
|
1605
|
-
*blobs: Union[str, Dict[str, Any], BlobProperties],
|
1606
|
-
**kwargs: Any
|
1607
|
-
):
|
1608
|
-
timeout = kwargs.pop('timeout', None)
|
1609
|
-
raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
|
1610
|
-
rehydrate_priority = kwargs.pop('rehydrate_priority', None)
|
1611
|
-
if_tags = kwargs.pop('if_tags_match_condition', None)
|
1612
|
-
kwargs.update({'raise_on_any_failure': raise_on_any_failure,
|
1613
|
-
'sas': self._query_str.replace('?', '&'),
|
1614
|
-
'timeout': '&timeout=' + str(timeout) if timeout else "",
|
1615
|
-
'path': self.container_name,
|
1616
|
-
'restype': 'restype=container&'
|
1617
|
-
})
|
1618
|
-
|
1619
|
-
reqs = []
|
1620
|
-
for blob in blobs:
|
1621
|
-
blob_name = _get_blob_name(blob)
|
1622
|
-
container_name = self.container_name
|
1623
|
-
|
1624
|
-
try:
|
1625
|
-
tier = blob_tier or blob.get('blob_tier')
|
1626
|
-
query_parameters, header_parameters = self._generate_set_tiers_subrequest_options(
|
1627
|
-
tier=tier,
|
1628
|
-
snapshot=blob.get('snapshot'),
|
1629
|
-
version_id=blob.get('version_id'),
|
1630
|
-
rehydrate_priority=rehydrate_priority or blob.get('rehydrate_priority'),
|
1631
|
-
lease_access_conditions=blob.get('lease_id'),
|
1632
|
-
if_tags=if_tags or blob.get('if_tags_match_condition'),
|
1633
|
-
timeout=timeout or blob.get('timeout')
|
1634
|
-
)
|
1635
|
-
except AttributeError:
|
1636
|
-
query_parameters, header_parameters = self._generate_set_tiers_subrequest_options(
|
1637
|
-
blob_tier, rehydrate_priority=rehydrate_priority, if_tags=if_tags)
|
1638
|
-
|
1639
|
-
req = HttpRequest(
|
1640
|
-
"PUT",
|
1641
|
-
f"/{quote(container_name)}/{quote(blob_name, safe='/~')}{self._query_str}",
|
1642
|
-
headers=header_parameters
|
1643
|
-
)
|
1644
|
-
req.format_parameters(query_parameters)
|
1645
|
-
reqs.append(req)
|
1646
|
-
|
1647
|
-
return reqs, kwargs
|
1648
|
-
|
1649
1426
|
@distributed_trace
|
1650
1427
|
def set_standard_blob_tier_blobs(
|
1651
|
-
self, standard_blob_tier: Optional[Union[str,
|
1428
|
+
self, standard_blob_tier: Optional[Union[str, "StandardBlobTier"]],
|
1652
1429
|
*blobs: Union[str, Dict[str, Any], BlobProperties],
|
1653
1430
|
**kwargs: Any
|
1654
1431
|
) -> Iterator["HttpResponse"]:
|
@@ -1717,13 +1494,19 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1717
1494
|
:return: An iterator of responses, one for each blob in order
|
1718
1495
|
:rtype: Iterator[~azure.core.pipeline.transport.HttpResponse]
|
1719
1496
|
"""
|
1720
|
-
reqs, options =
|
1497
|
+
reqs, options = _generate_set_tiers_options(
|
1498
|
+
self._query_str,
|
1499
|
+
self.container_name,
|
1500
|
+
standard_blob_tier,
|
1501
|
+
self._client,
|
1502
|
+
*blobs,
|
1503
|
+
**kwargs)
|
1721
1504
|
|
1722
1505
|
return self._batch_send(*reqs, **options)
|
1723
1506
|
|
1724
1507
|
@distributed_trace
|
1725
1508
|
def set_premium_page_blob_tier_blobs(
|
1726
|
-
self, premium_page_blob_tier: Optional[Union[str,
|
1509
|
+
self, premium_page_blob_tier: Optional[Union[str, "PremiumPageBlobTier"]],
|
1727
1510
|
*blobs: Union[str, Dict[str, Any], BlobProperties],
|
1728
1511
|
**kwargs: Any
|
1729
1512
|
) -> Iterator["HttpResponse"]:
|
@@ -1770,15 +1553,21 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1770
1553
|
:return: An iterator of responses, one for each blob in order
|
1771
1554
|
:rtype: Iterator[~azure.core.pipeline.transport.HttpResponse]
|
1772
1555
|
"""
|
1773
|
-
reqs, options =
|
1556
|
+
reqs, options = _generate_set_tiers_options(
|
1557
|
+
self._query_str,
|
1558
|
+
self.container_name,
|
1559
|
+
premium_page_blob_tier,
|
1560
|
+
self._client,
|
1561
|
+
*blobs,
|
1562
|
+
**kwargs)
|
1774
1563
|
|
1775
1564
|
return self._batch_send(*reqs, **options)
|
1776
1565
|
|
1777
1566
|
def get_blob_client(
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1567
|
+
self, blob: str,
|
1568
|
+
snapshot: Optional[str] = None,
|
1569
|
+
*,
|
1570
|
+
version_id: Optional[str] = None
|
1782
1571
|
) -> BlobClient:
|
1783
1572
|
"""Get a client to interact with the specified blob.
|
1784
1573
|
|
@@ -1809,7 +1598,9 @@ class ContainerClient(StorageAccountHostsMixin, StorageEncryptionMixin): # py
|
|
1809
1598
|
"Please use 'BlobProperties.name' or any other str input type instead.",
|
1810
1599
|
DeprecationWarning
|
1811
1600
|
)
|
1812
|
-
|
1601
|
+
blob_name = blob.get('name')
|
1602
|
+
else:
|
1603
|
+
blob_name = blob
|
1813
1604
|
_pipeline = Pipeline(
|
1814
1605
|
transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
|
1815
1606
|
policies=self._pipeline._impl_policies # pylint: disable = protected-access
|