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
@@ -5,64 +5,62 @@
|
|
5
5
|
# license information.
|
6
6
|
# --------------------------------------------------------------------------
|
7
7
|
|
8
|
+
from typing import Callable, List, Optional
|
8
9
|
from urllib.parse import unquote
|
9
10
|
|
10
|
-
from azure.core.async_paging import
|
11
|
+
from azure.core.async_paging import AsyncItemPaged, AsyncPageIterator
|
11
12
|
from azure.core.exceptions import HttpResponseError
|
12
13
|
|
13
14
|
from .._deserialize import (
|
14
15
|
get_blob_properties_from_generated_code,
|
15
16
|
load_many_xml_nodes,
|
16
17
|
load_xml_int,
|
17
|
-
load_xml_string
|
18
|
+
load_xml_string
|
18
19
|
)
|
19
20
|
from .._generated.models import BlobItemInternal, BlobPrefix as GenBlobPrefix
|
20
21
|
from .._models import BlobProperties
|
21
22
|
from .._shared.models import DictMixin
|
22
23
|
from .._shared.response_handlers import (
|
23
|
-
return_context_and_deserialized,
|
24
|
-
return_raw_deserialized,
|
25
24
|
process_storage_error,
|
25
|
+
return_context_and_deserialized,
|
26
|
+
return_raw_deserialized
|
26
27
|
)
|
27
28
|
|
28
29
|
|
29
30
|
class BlobPropertiesPaged(AsyncPageIterator):
|
30
|
-
"""An Iterable of Blob properties.
|
31
|
+
"""An Iterable of Blob properties."""
|
32
|
+
|
33
|
+
service_endpoint: Optional[str]
|
34
|
+
"""The service URL."""
|
35
|
+
prefix: Optional[str]
|
36
|
+
"""A blob name prefix being used to filter the list."""
|
37
|
+
marker: Optional[str]
|
38
|
+
"""The continuation token of the current page of results."""
|
39
|
+
results_per_page: Optional[int]
|
40
|
+
"""The maximum number of results retrieved per API call."""
|
41
|
+
continuation_token: Optional[str]
|
42
|
+
"""The continuation token to retrieve the next page of results."""
|
43
|
+
location_mode: Optional[str]
|
44
|
+
"""The location mode being used to list results. The available
|
45
|
+
options include "primary" and "secondary"."""
|
46
|
+
current_page: Optional[List[BlobProperties]]
|
47
|
+
"""The current page of listed results."""
|
48
|
+
container: Optional[str]
|
49
|
+
"""The container that the blobs are listed from."""
|
50
|
+
delimiter: Optional[str]
|
51
|
+
"""A delimiting character used for hierarchy listing."""
|
52
|
+
command: Callable
|
53
|
+
"""Function to retrieve the next page of items."""
|
31
54
|
|
32
|
-
:ivar str service_endpoint: The service URL.
|
33
|
-
:ivar str prefix: A blob name prefix being used to filter the list.
|
34
|
-
:ivar str marker: The continuation token of the current page of results.
|
35
|
-
:ivar int results_per_page: The maximum number of results retrieved per API call.
|
36
|
-
:ivar str location_mode: The location mode being used to list results. The available
|
37
|
-
options include "primary" and "secondary".
|
38
|
-
:ivar current_page: The current page of listed results.
|
39
|
-
:vartype current_page: list(~azure.storage.blob.models.BlobProperties)
|
40
|
-
:ivar str container: The container that the blobs are listed from.
|
41
|
-
:ivar str delimiter: A delimiting character used for hierarchy listing.
|
42
|
-
|
43
|
-
:param callable command: Function to retrieve the next page of items.
|
44
|
-
:param str container: The container that the blobs are listed from.
|
45
|
-
:param str prefix: Filters the results to return only blobs whose names
|
46
|
-
begin with the specified prefix.
|
47
|
-
:param int results_per_page: The maximum number of blobs to retrieve per
|
48
|
-
call.
|
49
|
-
:param str continuation_token: An opaque continuation token.
|
50
|
-
:param str delimiter:
|
51
|
-
Used to capture blobs whose names begin with the same substring up to
|
52
|
-
the appearance of the delimiter character. The delimiter may be a single
|
53
|
-
character or a string.
|
54
|
-
:param location_mode: Specifies the location the request should be sent to.
|
55
|
-
This mode only applies for RA-GRS accounts which allow secondary read access.
|
56
|
-
Options include 'primary' or 'secondary'.
|
57
|
-
"""
|
58
55
|
def __init__(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
self, command: Callable,
|
57
|
+
container: Optional[str] = None,
|
58
|
+
prefix: Optional[str] = None,
|
59
|
+
results_per_page: Optional[int] = None,
|
60
|
+
continuation_token: Optional[str] = None,
|
61
|
+
delimiter: Optional[str] = None,
|
62
|
+
location_mode: Optional[str] = None,
|
63
|
+
) -> None:
|
66
64
|
super(BlobPropertiesPaged, self).__init__(
|
67
65
|
get_next=self._get_next_cb,
|
68
66
|
extract_data=self._extract_data_cb,
|
@@ -105,44 +103,44 @@ class BlobPropertiesPaged(AsyncPageIterator):
|
|
105
103
|
return item
|
106
104
|
if isinstance(item, BlobItemInternal):
|
107
105
|
blob = get_blob_properties_from_generated_code(item) # pylint: disable=protected-access
|
108
|
-
blob.container = self.container
|
106
|
+
blob.container = self.container # type: ignore [assignment]
|
109
107
|
return blob
|
110
108
|
return item
|
111
109
|
|
112
110
|
|
113
111
|
class BlobNamesPaged(AsyncPageIterator):
|
114
|
-
"""An Iterable of Blob names.
|
115
|
-
|
116
|
-
:
|
117
|
-
|
118
|
-
:
|
119
|
-
|
120
|
-
:
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
:
|
125
|
-
|
126
|
-
:
|
127
|
-
|
128
|
-
|
129
|
-
:
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
:
|
136
|
-
|
137
|
-
|
138
|
-
"""
|
112
|
+
"""An Iterable of Blob names."""
|
113
|
+
|
114
|
+
service_endpoint: Optional[str]
|
115
|
+
"""The service URL."""
|
116
|
+
prefix: Optional[str]
|
117
|
+
"""A blob name prefix being used to filter the list."""
|
118
|
+
marker: Optional[str]
|
119
|
+
"""The continuation token of the current page of results."""
|
120
|
+
results_per_page: Optional[int]
|
121
|
+
"""The maximum number of blobs to retrieve per call."""
|
122
|
+
continuation_token: Optional[str]
|
123
|
+
"""The continuation token to retrieve the next page of results."""
|
124
|
+
location_mode: Optional[str]
|
125
|
+
"""The location mode being used to list results. The available
|
126
|
+
options include "primary" and "secondary"."""
|
127
|
+
current_page: Optional[List[BlobProperties]]
|
128
|
+
"""The current page of listed results."""
|
129
|
+
container: Optional[str]
|
130
|
+
"""The container that the blobs are listed from."""
|
131
|
+
delimiter: Optional[str]
|
132
|
+
"""A delimiting character used for hierarchy listing."""
|
133
|
+
command: Callable
|
134
|
+
"""Function to retrieve the next page of items."""
|
135
|
+
|
139
136
|
def __init__(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
137
|
+
self, command: Callable,
|
138
|
+
container: Optional[str] = None,
|
139
|
+
prefix: Optional[str] = None,
|
140
|
+
results_per_page: Optional[int] = None,
|
141
|
+
continuation_token: Optional[str] = None,
|
142
|
+
location_mode: Optional[str] = None
|
143
|
+
) -> None:
|
146
144
|
super(BlobNamesPaged, self).__init__(
|
147
145
|
get_next=self._get_next_cb,
|
148
146
|
extract_data=self._extract_data_cb,
|
@@ -187,32 +185,32 @@ class BlobPrefix(AsyncItemPaged, DictMixin):
|
|
187
185
|
"""An Iterable of Blob properties.
|
188
186
|
|
189
187
|
Returned from walk_blobs when a delimiter is used.
|
190
|
-
Can be thought of as a virtual blob directory.
|
191
|
-
|
192
|
-
:
|
193
|
-
|
194
|
-
:
|
195
|
-
|
196
|
-
:
|
197
|
-
|
198
|
-
:
|
199
|
-
|
200
|
-
:
|
201
|
-
|
202
|
-
:
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
:
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
188
|
+
Can be thought of as a virtual blob directory."""
|
189
|
+
|
190
|
+
name: str
|
191
|
+
"""The prefix, or "directory name" of the blob."""
|
192
|
+
service_endpoint: Optional[str]
|
193
|
+
"""The service URL."""
|
194
|
+
prefix: str
|
195
|
+
"""A blob name prefix being used to filter the list."""
|
196
|
+
marker: Optional[str]
|
197
|
+
"""The continuation token of the current page of results."""
|
198
|
+
results_per_page: Optional[int]
|
199
|
+
"""The maximum number of results retrieved per API call."""
|
200
|
+
next_marker: Optional[str]
|
201
|
+
"""The continuation token to retrieve the next page of results."""
|
202
|
+
location_mode: str
|
203
|
+
"""The location mode being used to list results. The available
|
204
|
+
options include "primary" and "secondary"."""
|
205
|
+
current_page: Optional[List[BlobProperties]]
|
206
|
+
"""The current page of listed results."""
|
207
|
+
delimiter: str
|
208
|
+
"""A delimiting character used for hierarchy listing."""
|
209
|
+
command: Callable
|
210
|
+
"""Function to retrieve the next page of items."""
|
211
|
+
container: str
|
212
|
+
"""The name of the container."""
|
213
|
+
|
216
214
|
def __init__(self, *args, **kwargs):
|
217
215
|
super(BlobPrefix, self).__init__(*args, page_iterator_class=BlobPrefixPaged, **kwargs)
|
218
216
|
self.name = kwargs.get('prefix')
|
@@ -6,35 +6,47 @@
|
|
6
6
|
# pylint: disable=too-few-public-methods, too-many-instance-attributes
|
7
7
|
# pylint: disable=super-init-not-called, too-many-lines
|
8
8
|
|
9
|
+
from typing import Callable, List, Optional, TYPE_CHECKING
|
10
|
+
|
9
11
|
from azure.core.async_paging import AsyncPageIterator
|
10
12
|
from azure.core.exceptions import HttpResponseError
|
11
|
-
from .._deserialize import parse_tags
|
12
13
|
|
14
|
+
from .._deserialize import parse_tags
|
15
|
+
from .._generated.models import FilterBlobItem
|
13
16
|
from .._models import ContainerProperties, FilteredBlob, parse_page_list
|
14
|
-
from .._shared.response_handlers import
|
17
|
+
from .._shared.response_handlers import process_storage_error, return_context_and_deserialized
|
15
18
|
|
16
|
-
|
19
|
+
if TYPE_CHECKING:
|
20
|
+
from .._models import BlobProperties
|
17
21
|
|
18
22
|
|
19
23
|
class ContainerPropertiesPaged(AsyncPageIterator):
|
20
24
|
"""An Iterable of Container properties.
|
21
25
|
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:ivar str marker: The continuation token of the current page of results.
|
25
|
-
:ivar int results_per_page: The maximum number of results retrieved per API call.
|
26
|
-
:ivar str location_mode: The location mode being used to list results. The available
|
27
|
-
options include "primary" and "secondary".
|
28
|
-
:ivar current_page: The current page of listed results.
|
29
|
-
:vartype current_page: list(~azure.storage.blob.models.ContainerProperties)
|
30
|
-
|
31
|
-
:param callable command: Function to retrieve the next page of items.
|
32
|
-
:param str prefix: Filters the results to return only containers whose names
|
26
|
+
:param Callable command: Function to retrieve the next page of items.
|
27
|
+
:param Optional[str] prefix: Filters the results to return only containers whose names
|
33
28
|
begin with the specified prefix.
|
34
|
-
:param int results_per_page: The maximum number of container names to retrieve per
|
29
|
+
:param Optional[int] results_per_page: The maximum number of container names to retrieve per
|
35
30
|
call.
|
36
|
-
:param str continuation_token: An opaque continuation token.
|
31
|
+
:param Optional[str] continuation_token: An opaque continuation token.
|
37
32
|
"""
|
33
|
+
|
34
|
+
service_endpoint: Optional[str]
|
35
|
+
"""The service URL."""
|
36
|
+
prefix: Optional[str]
|
37
|
+
"""A container name prefix being used to filter the list."""
|
38
|
+
marker: Optional[str]
|
39
|
+
"""The continuation token of the current page of results."""
|
40
|
+
results_per_page: Optional[int]
|
41
|
+
"""The maximum number of results retrieved per API call."""
|
42
|
+
continuation_token: Optional[str]
|
43
|
+
"""The continuation token to retrieve the next page of results."""
|
44
|
+
location_mode: Optional[str]
|
45
|
+
"""The location mode being used to list results. The available
|
46
|
+
options include "primary" and "secondary"."""
|
47
|
+
current_page: List[ContainerProperties]
|
48
|
+
"""The current page of listed results."""
|
49
|
+
|
38
50
|
def __init__(self, command, prefix=None, results_per_page=None, continuation_token=None):
|
39
51
|
super(ContainerPropertiesPaged, self).__init__(
|
40
52
|
get_next=self._get_next_cb,
|
@@ -77,31 +89,41 @@ class ContainerPropertiesPaged(AsyncPageIterator):
|
|
77
89
|
class FilteredBlobPaged(AsyncPageIterator):
|
78
90
|
"""An Iterable of Blob properties.
|
79
91
|
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:ivar int results_per_page: The maximum number of results retrieved per API call.
|
84
|
-
:ivar str continuation_token: The continuation token to retrieve the next page of results.
|
85
|
-
:ivar str location_mode: The location mode being used to list results. The available
|
86
|
-
options include "primary" and "secondary".
|
87
|
-
:ivar current_page: The current page of listed results.
|
88
|
-
:vartype current_page: list(~azure.storage.blob.BlobProperties)
|
89
|
-
:ivar str container: The container that the blobs are listed from.
|
90
|
-
:param callable command: Function to retrieve the next page of items.
|
91
|
-
:param str container: The name of the container.
|
92
|
-
:param int results_per_page: The maximum number of blobs to retrieve per
|
92
|
+
:param Callable command: Function to retrieve the next page of items.
|
93
|
+
:param Optional[str] container: The name of the container.
|
94
|
+
:param Optional[int] results_per_page: The maximum number of blobs to retrieve per
|
93
95
|
call.
|
94
|
-
:param str continuation_token: An opaque continuation token.
|
95
|
-
:param location_mode:
|
96
|
-
|
97
|
-
Options include 'primary' or 'secondary'.
|
96
|
+
:param Optional[str] continuation_token: An opaque continuation token.
|
97
|
+
:param Optional[str] location_mode:
|
98
|
+
Specifies the location the request should be sent to. This mode only applies for RA-GRS accounts
|
99
|
+
which allow secondary read access. Options include 'primary' or 'secondary'.
|
98
100
|
"""
|
101
|
+
|
102
|
+
service_endpoint: Optional[str]
|
103
|
+
"""The service URL."""
|
104
|
+
prefix: Optional[str]
|
105
|
+
"""A blob name prefix being used to filter the list."""
|
106
|
+
marker: Optional[str]
|
107
|
+
"""The continuation token of the current page of results."""
|
108
|
+
results_per_page: Optional[int]
|
109
|
+
"""The maximum number of results retrieved per API call."""
|
110
|
+
continuation_token: Optional[str]
|
111
|
+
"""The continuation token to retrieve the next page of results."""
|
112
|
+
location_mode: Optional[str]
|
113
|
+
"""The location mode being used to list results. The available
|
114
|
+
options include "primary" and "secondary"."""
|
115
|
+
current_page: Optional[List["BlobProperties"]]
|
116
|
+
"""The current page of listed results."""
|
117
|
+
container: Optional[str]
|
118
|
+
"""The container that the blobs are listed from."""
|
119
|
+
|
99
120
|
def __init__(
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
121
|
+
self, command: Callable,
|
122
|
+
container: Optional[str] = None,
|
123
|
+
results_per_page: Optional[int] = None,
|
124
|
+
continuation_token: Optional[str] = None,
|
125
|
+
location_mode: Optional[str] = None
|
126
|
+
) -> None:
|
105
127
|
super(FilteredBlobPaged, self).__init__(
|
106
128
|
get_next=self._get_next_cb,
|
107
129
|
extract_data=self._extract_data_cb,
|
@@ -6,23 +6,10 @@
|
|
6
6
|
|
7
7
|
import inspect
|
8
8
|
from io import SEEK_SET, UnsupportedOperation
|
9
|
-
from typing import TypeVar, TYPE_CHECKING
|
9
|
+
from typing import Any, cast, Dict, IO, Optional, TypeVar, TYPE_CHECKING
|
10
10
|
|
11
|
-
from azure.core.exceptions import
|
11
|
+
from azure.core.exceptions import HttpResponseError, ResourceModifiedError
|
12
12
|
|
13
|
-
from .._shared.response_handlers import process_storage_error, return_response_headers
|
14
|
-
from .._shared.uploads_async import (
|
15
|
-
upload_data_chunks,
|
16
|
-
upload_substream_blocks,
|
17
|
-
BlockBlobChunkUploader,
|
18
|
-
PageBlobChunkUploader,
|
19
|
-
AppendBlobChunkUploader
|
20
|
-
)
|
21
|
-
from .._generated.models import (
|
22
|
-
BlockLookupList,
|
23
|
-
AppendPositionAccessConditions,
|
24
|
-
ModifiedAccessConditions,
|
25
|
-
)
|
26
13
|
from ._encryption_async import GCMBlobEncryptionStream
|
27
14
|
from .._encryption import (
|
28
15
|
encrypt_blob,
|
@@ -32,23 +19,39 @@ from .._encryption import (
|
|
32
19
|
_ENCRYPTION_PROTOCOL_V1,
|
33
20
|
_ENCRYPTION_PROTOCOL_V2
|
34
21
|
)
|
35
|
-
from ..
|
22
|
+
from .._generated.models import (
|
23
|
+
AppendPositionAccessConditions,
|
24
|
+
BlockLookupList,
|
25
|
+
ModifiedAccessConditions
|
26
|
+
)
|
27
|
+
from .._shared.response_handlers import process_storage_error, return_response_headers
|
28
|
+
from .._shared.uploads_async import (
|
29
|
+
AppendBlobChunkUploader,
|
30
|
+
BlockBlobChunkUploader,
|
31
|
+
PageBlobChunkUploader,
|
32
|
+
upload_data_chunks,
|
33
|
+
upload_substream_blocks
|
34
|
+
)
|
35
|
+
from .._upload_helpers import _any_conditions, _convert_mod_error
|
36
36
|
|
37
37
|
if TYPE_CHECKING:
|
38
|
+
from .._generated.aio.operations import AppendBlobOperations, BlockBlobOperations, PageBlobOperations
|
39
|
+
from .._shared.models import StorageConfiguration
|
38
40
|
BlobLeaseClient = TypeVar("BlobLeaseClient")
|
39
41
|
|
40
42
|
|
41
43
|
async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statements
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
client: "BlockBlobOperations",
|
45
|
+
stream: IO,
|
46
|
+
overwrite: bool,
|
47
|
+
encryption_options: Dict[str, Any],
|
48
|
+
blob_settings: "StorageConfiguration",
|
49
|
+
headers: Dict[str, Any],
|
50
|
+
validate_content: bool,
|
51
|
+
max_concurrency: Optional[int],
|
52
|
+
length: Optional[int] = None,
|
53
|
+
**kwargs: Any
|
54
|
+
) -> Dict[str, Any]:
|
52
55
|
try:
|
53
56
|
if not overwrite and not _any_conditions(**kwargs):
|
54
57
|
kwargs['modified_access_conditions'].if_none_match = '*'
|
@@ -67,18 +70,20 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
67
70
|
|
68
71
|
# Do single put if the size is smaller than config.max_single_put_size
|
69
72
|
if adjusted_count is not None and (adjusted_count <= blob_settings.max_single_put_size):
|
70
|
-
data = stream.read(length)
|
73
|
+
data = stream.read(length or -1)
|
71
74
|
if inspect.isawaitable(data):
|
72
75
|
data = await data
|
73
76
|
if not isinstance(data, bytes):
|
74
77
|
raise TypeError('Blob data should be of type bytes.')
|
75
78
|
|
76
79
|
if encryption_options.get('key'):
|
80
|
+
if not isinstance(data, bytes):
|
81
|
+
raise TypeError('Blob data should be of type bytes.')
|
77
82
|
encryption_data, data = encrypt_blob(data, encryption_options['key'], encryption_options['version'])
|
78
83
|
headers['x-ms-meta-encryptiondata'] = encryption_data
|
79
84
|
|
80
|
-
response = await client.upload(
|
81
|
-
body=data,
|
85
|
+
response = cast(Dict[str, Any], await client.upload(
|
86
|
+
body=data, # type: ignore [arg-type]
|
82
87
|
content_length=adjusted_count,
|
83
88
|
blob_http_headers=blob_headers,
|
84
89
|
headers=headers,
|
@@ -91,7 +96,7 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
91
96
|
immutability_policy_expiry=immutability_policy_expiry,
|
92
97
|
immutability_policy_mode=immutability_policy_mode,
|
93
98
|
legal_hold=legal_hold,
|
94
|
-
**kwargs)
|
99
|
+
**kwargs))
|
95
100
|
|
96
101
|
if progress_hook:
|
97
102
|
await progress_hook(adjusted_count, adjusted_count)
|
@@ -108,10 +113,10 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
108
113
|
total_size = length
|
109
114
|
encryptor, padder = None, None
|
110
115
|
if encryption_options and encryption_options.get('key'):
|
111
|
-
cek, iv,
|
116
|
+
cek, iv, encryption_metadata = generate_blob_encryption_data(
|
112
117
|
encryption_options['key'],
|
113
118
|
encryption_options['version'])
|
114
|
-
headers['x-ms-meta-encryptiondata'] =
|
119
|
+
headers['x-ms-meta-encryptiondata'] = encryption_metadata
|
115
120
|
|
116
121
|
if encryption_options['version'] == _ENCRYPTION_PROTOCOL_V1:
|
117
122
|
encryptor, padder = get_blob_encryptor_and_padder(cek, iv, True)
|
@@ -121,7 +126,9 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
121
126
|
# Adjust total_size for encryption V2
|
122
127
|
total_size = adjusted_count
|
123
128
|
# V2 wraps the data stream with an encryption stream
|
124
|
-
|
129
|
+
if cek is None:
|
130
|
+
raise ValueError("Generate encryption metadata failed. 'cek' is None.")
|
131
|
+
stream = GCMBlobEncryptionStream(cek, stream) # type: ignore [assignment]
|
125
132
|
|
126
133
|
block_ids = await upload_data_chunks(
|
127
134
|
service=client,
|
@@ -153,7 +160,7 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
153
160
|
|
154
161
|
block_lookup = BlockLookupList(committed=[], uncommitted=[], latest=[])
|
155
162
|
block_lookup.latest = block_ids
|
156
|
-
return await client.commit_block_list(
|
163
|
+
return cast(Dict[str, Any], await client.commit_block_list(
|
157
164
|
block_lookup,
|
158
165
|
blob_http_headers=blob_headers,
|
159
166
|
cls=return_response_headers,
|
@@ -164,7 +171,7 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
164
171
|
immutability_policy_expiry=immutability_policy_expiry,
|
165
172
|
immutability_policy_mode=immutability_policy_mode,
|
166
173
|
legal_hold=legal_hold,
|
167
|
-
**kwargs)
|
174
|
+
**kwargs))
|
168
175
|
except HttpResponseError as error:
|
169
176
|
try:
|
170
177
|
process_storage_error(error)
|
@@ -175,16 +182,17 @@ async def upload_block_blob( # pylint: disable=too-many-locals, too-many-statem
|
|
175
182
|
|
176
183
|
|
177
184
|
async def upload_page_blob(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
client: "PageBlobOperations",
|
186
|
+
overwrite: bool,
|
187
|
+
encryption_options: Dict[str, Any],
|
188
|
+
blob_settings: "StorageConfiguration",
|
189
|
+
headers: Dict[str, Any],
|
190
|
+
stream: IO,
|
191
|
+
length: Optional[int] = None,
|
192
|
+
validate_content: Optional[bool] = None,
|
193
|
+
max_concurrency: Optional[int] = None,
|
194
|
+
**kwargs: Any
|
195
|
+
) -> Dict[str, Any]:
|
188
196
|
try:
|
189
197
|
if not overwrite and not _any_conditions(**kwargs):
|
190
198
|
kwargs['modified_access_conditions'].if_none_match = '*'
|
@@ -210,18 +218,18 @@ async def upload_page_blob(
|
|
210
218
|
blob_tags_string = kwargs.pop('blob_tags_string', None)
|
211
219
|
progress_hook = kwargs.pop('progress_hook', None)
|
212
220
|
|
213
|
-
response = await client.create(
|
221
|
+
response = cast(Dict[str, Any], await client.create(
|
214
222
|
content_length=0,
|
215
223
|
blob_content_length=length,
|
216
|
-
blob_sequence_number=None,
|
224
|
+
blob_sequence_number=None, # type: ignore [arg-type]
|
217
225
|
blob_http_headers=kwargs.pop('blob_headers', None),
|
218
226
|
blob_tags_string=blob_tags_string,
|
219
227
|
tier=tier,
|
220
228
|
cls=return_response_headers,
|
221
229
|
headers=headers,
|
222
|
-
**kwargs)
|
230
|
+
**kwargs))
|
223
231
|
if length == 0:
|
224
|
-
return response
|
232
|
+
return cast(Dict[str, Any], response)
|
225
233
|
|
226
234
|
if encryption_options and encryption_options.get('key'):
|
227
235
|
if encryption_options['version'] == _ENCRYPTION_PROTOCOL_V1:
|
@@ -230,7 +238,7 @@ async def upload_page_blob(
|
|
230
238
|
kwargs['padder'] = padder
|
231
239
|
|
232
240
|
kwargs['modified_access_conditions'] = ModifiedAccessConditions(if_match=response['etag'])
|
233
|
-
return await upload_data_chunks(
|
241
|
+
return cast(Dict[str, Any], await upload_data_chunks(
|
234
242
|
service=client,
|
235
243
|
uploader_class=PageBlobChunkUploader,
|
236
244
|
total_size=length,
|
@@ -240,7 +248,7 @@ async def upload_page_blob(
|
|
240
248
|
validate_content=validate_content,
|
241
249
|
progress_hook=progress_hook,
|
242
250
|
headers=headers,
|
243
|
-
**kwargs)
|
251
|
+
**kwargs))
|
244
252
|
|
245
253
|
except HttpResponseError as error:
|
246
254
|
try:
|
@@ -252,16 +260,17 @@ async def upload_page_blob(
|
|
252
260
|
|
253
261
|
|
254
262
|
async def upload_append_blob( # pylint: disable=unused-argument
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
263
|
+
client: "AppendBlobOperations",
|
264
|
+
overwrite: bool,
|
265
|
+
encryption_options: Dict[str, Any],
|
266
|
+
blob_settings: "StorageConfiguration",
|
267
|
+
headers: Dict[str, Any],
|
268
|
+
stream: IO,
|
269
|
+
length: Optional[int] = None,
|
270
|
+
validate_content: Optional[bool] = None,
|
271
|
+
max_concurrency: Optional[int] = None,
|
272
|
+
**kwargs: Any
|
273
|
+
) -> Dict[str, Any]:
|
265
274
|
try:
|
266
275
|
if length == 0:
|
267
276
|
return {}
|
@@ -280,7 +289,7 @@ async def upload_append_blob( # pylint: disable=unused-argument
|
|
280
289
|
headers=headers,
|
281
290
|
blob_tags_string=blob_tags_string,
|
282
291
|
**kwargs)
|
283
|
-
return await upload_data_chunks(
|
292
|
+
return cast(Dict[str, Any], await upload_data_chunks(
|
284
293
|
service=client,
|
285
294
|
uploader_class=AppendBlobChunkUploader,
|
286
295
|
total_size=length,
|
@@ -291,9 +300,9 @@ async def upload_append_blob( # pylint: disable=unused-argument
|
|
291
300
|
append_position_access_conditions=append_conditions,
|
292
301
|
progress_hook=progress_hook,
|
293
302
|
headers=headers,
|
294
|
-
**kwargs)
|
303
|
+
**kwargs))
|
295
304
|
except HttpResponseError as error:
|
296
|
-
if error.response.status_code != 404:
|
305
|
+
if error.response.status_code != 404: # type: ignore [union-attr]
|
297
306
|
raise
|
298
307
|
# rewind the request body if it is a stream
|
299
308
|
if hasattr(stream, 'read'):
|
@@ -309,7 +318,7 @@ async def upload_append_blob( # pylint: disable=unused-argument
|
|
309
318
|
headers=headers,
|
310
319
|
blob_tags_string=blob_tags_string,
|
311
320
|
**kwargs)
|
312
|
-
return await upload_data_chunks(
|
321
|
+
return cast(Dict[str, Any], await upload_data_chunks(
|
313
322
|
service=client,
|
314
323
|
uploader_class=AppendBlobChunkUploader,
|
315
324
|
total_size=length,
|
@@ -320,6 +329,6 @@ async def upload_append_blob( # pylint: disable=unused-argument
|
|
320
329
|
append_position_access_conditions=append_conditions,
|
321
330
|
progress_hook=progress_hook,
|
322
331
|
headers=headers,
|
323
|
-
**kwargs)
|
332
|
+
**kwargs))
|
324
333
|
except HttpResponseError as error:
|
325
334
|
process_storage_error(error)
|