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.
Files changed (42) hide show
  1. azure/storage/blob/__init__.py +19 -18
  2. azure/storage/blob/_blob_client.py +417 -1507
  3. azure/storage/blob/_blob_client_helpers.py +1242 -0
  4. azure/storage/blob/_blob_service_client.py +82 -101
  5. azure/storage/blob/_blob_service_client_helpers.py +27 -0
  6. azure/storage/blob/_container_client.py +147 -356
  7. azure/storage/blob/_container_client_helpers.py +261 -0
  8. azure/storage/blob/_deserialize.py +68 -44
  9. azure/storage/blob/_download.py +114 -90
  10. azure/storage/blob/_encryption.py +14 -7
  11. azure/storage/blob/_lease.py +47 -58
  12. azure/storage/blob/_list_blobs_helper.py +129 -135
  13. azure/storage/blob/_models.py +479 -276
  14. azure/storage/blob/_quick_query_helper.py +30 -31
  15. azure/storage/blob/_serialize.py +38 -56
  16. azure/storage/blob/_shared/avro/datafile.py +1 -1
  17. azure/storage/blob/_shared/avro/datafile_async.py +1 -1
  18. azure/storage/blob/_shared/base_client.py +1 -1
  19. azure/storage/blob/_shared/base_client_async.py +1 -1
  20. azure/storage/blob/_shared/policies.py +8 -6
  21. azure/storage/blob/_shared/policies_async.py +3 -1
  22. azure/storage/blob/_shared/response_handlers.py +6 -2
  23. azure/storage/blob/_shared/shared_access_signature.py +2 -2
  24. azure/storage/blob/_shared/uploads.py +1 -1
  25. azure/storage/blob/_shared/uploads_async.py +1 -1
  26. azure/storage/blob/_shared_access_signature.py +70 -53
  27. azure/storage/blob/_upload_helpers.py +75 -68
  28. azure/storage/blob/_version.py +1 -1
  29. azure/storage/blob/aio/__init__.py +19 -11
  30. azure/storage/blob/aio/_blob_client_async.py +505 -255
  31. azure/storage/blob/aio/_blob_service_client_async.py +138 -87
  32. azure/storage/blob/aio/_container_client_async.py +260 -120
  33. azure/storage/blob/aio/_download_async.py +104 -87
  34. azure/storage/blob/aio/_lease_async.py +56 -55
  35. azure/storage/blob/aio/_list_blobs_helper.py +94 -96
  36. azure/storage/blob/aio/_models.py +60 -38
  37. azure/storage/blob/aio/_upload_helpers.py +75 -66
  38. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/METADATA +1 -1
  39. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/RECORD +42 -39
  40. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/LICENSE +0 -0
  41. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/WHEEL +0 -0
  42. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,261 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+
7
+ from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
8
+ from urllib.parse import quote, urlparse
9
+
10
+ from azure.core import MatchConditions
11
+ from azure.core.pipeline.transport import HttpRequest
12
+ from ._blob_client_helpers import _generic_delete_blob_options
13
+ from ._generated import AzureBlobStorage
14
+ from ._models import BlobProperties
15
+ from ._shared.base_client import parse_query
16
+
17
+ if TYPE_CHECKING:
18
+ from azure.storage.blob import RehydratePriority
19
+ from urllib.parse import ParseResult
20
+ from ._generated.models import LeaseAccessConditions, ModifiedAccessConditions
21
+ from ._models import PremiumPageBlobTier, StandardBlobTier
22
+
23
+
24
+ def _parse_url(account_url: str, container_name: str) -> Tuple["ParseResult", Any]:
25
+ try:
26
+ if not account_url.lower().startswith('http'):
27
+ account_url = "https://" + account_url
28
+ except AttributeError as exc:
29
+ raise ValueError("Container URL must be a string.") from exc
30
+ parsed_url = urlparse(account_url.rstrip('/'))
31
+ if not container_name:
32
+ raise ValueError("Please specify a container name.")
33
+ if not parsed_url.netloc:
34
+ raise ValueError(f"Invalid URL: {account_url}")
35
+
36
+ _, sas_token = parse_query(parsed_url.query)
37
+
38
+ return parsed_url, sas_token
39
+
40
+ def _format_url(container_name: Union[bytes, str], hostname: str, scheme: str, query_str: str) -> str:
41
+ if isinstance(container_name, str):
42
+ container_name = container_name.encode('UTF-8')
43
+ return f"{scheme}://{hostname}/{quote(container_name)}{query_str}"
44
+
45
+ # This code is a copy from _generated.
46
+ # Once Autorest is able to provide request preparation this code should be removed.
47
+ def _generate_delete_blobs_subrequest_options(
48
+ client: AzureBlobStorage,
49
+ snapshot: Optional[str] = None,
50
+ version_id: Optional[str] = None,
51
+ delete_snapshots: Optional[str] = None,
52
+ lease_access_conditions: Optional["LeaseAccessConditions"] = None,
53
+ modified_access_conditions: Optional["ModifiedAccessConditions"] = None,
54
+ **kwargs
55
+ ) -> Tuple[Dict[str, Any], Dict[str, Any]]:
56
+ lease_id = None
57
+ if lease_access_conditions is not None:
58
+ lease_id = lease_access_conditions.lease_id
59
+ if_modified_since = None
60
+ if modified_access_conditions is not None:
61
+ if_modified_since = modified_access_conditions.if_modified_since
62
+ if_unmodified_since = None
63
+ if modified_access_conditions is not None:
64
+ if_unmodified_since = modified_access_conditions.if_unmodified_since
65
+ if_match = None
66
+ if modified_access_conditions is not None:
67
+ if_match = modified_access_conditions.if_match
68
+ if_none_match = None
69
+ if modified_access_conditions is not None:
70
+ if_none_match = modified_access_conditions.if_none_match
71
+ if_tags = None
72
+ if modified_access_conditions is not None:
73
+ if_tags = modified_access_conditions.if_tags
74
+
75
+ # Construct parameters
76
+ timeout = kwargs.pop('timeout', None)
77
+ query_parameters = {}
78
+ if snapshot is not None:
79
+ query_parameters['snapshot'] = client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
80
+ if version_id is not None:
81
+ query_parameters['versionid'] = client._serialize.query("version_id", version_id, 'str') # pylint: disable=protected-access
82
+ if timeout is not None:
83
+ query_parameters['timeout'] = client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
84
+
85
+ # Construct headers
86
+ header_parameters = {}
87
+ if delete_snapshots is not None:
88
+ header_parameters['x-ms-delete-snapshots'] = client._serialize.header( # pylint: disable=protected-access
89
+ "delete_snapshots", delete_snapshots, 'DeleteSnapshotsOptionType')
90
+ if lease_id is not None:
91
+ header_parameters['x-ms-lease-id'] = client._serialize.header( # pylint: disable=protected-access
92
+ "lease_id", lease_id, 'str')
93
+ if if_modified_since is not None:
94
+ header_parameters['If-Modified-Since'] = client._serialize.header( # pylint: disable=protected-access
95
+ "if_modified_since", if_modified_since, 'rfc-1123')
96
+ if if_unmodified_since is not None:
97
+ header_parameters['If-Unmodified-Since'] = client._serialize.header( # pylint: disable=protected-access
98
+ "if_unmodified_since", if_unmodified_since, 'rfc-1123')
99
+ if if_match is not None:
100
+ header_parameters['If-Match'] = client._serialize.header( # pylint: disable=protected-access
101
+ "if_match", if_match, 'str')
102
+ if if_none_match is not None:
103
+ header_parameters['If-None-Match'] = client._serialize.header( # pylint: disable=protected-access
104
+ "if_none_match", if_none_match, 'str')
105
+ if if_tags is not None:
106
+ header_parameters['x-ms-if-tags'] = client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
107
+
108
+ return query_parameters, header_parameters
109
+
110
+ def _generate_delete_blobs_options(
111
+ query_str: str,
112
+ container_name: str,
113
+ client: AzureBlobStorage,
114
+ *blobs: Union[str, Dict[str, Any], BlobProperties],
115
+ **kwargs: Any
116
+ ) -> Tuple[List[HttpRequest], Dict[str, Any]]:
117
+ timeout = kwargs.pop('timeout', None)
118
+ raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
119
+ delete_snapshots = kwargs.pop('delete_snapshots', None)
120
+ if_modified_since = kwargs.pop('if_modified_since', None)
121
+ if_unmodified_since = kwargs.pop('if_unmodified_since', None)
122
+ if_tags_match_condition = kwargs.pop('if_tags_match_condition', None)
123
+ kwargs.update({'raise_on_any_failure': raise_on_any_failure,
124
+ 'sas': query_str.replace('?', '&'),
125
+ 'timeout': '&timeout=' + str(timeout) if timeout else "",
126
+ 'path': container_name,
127
+ 'restype': 'restype=container&'
128
+ })
129
+
130
+ reqs = []
131
+ for blob in blobs:
132
+ if not isinstance(blob, str):
133
+ blob_name = blob.get('name')
134
+ options = _generic_delete_blob_options( # pylint: disable=protected-access
135
+ snapshot=blob.get('snapshot'),
136
+ version_id=blob.get('version_id'),
137
+ delete_snapshots=delete_snapshots or blob.get('delete_snapshots'),
138
+ lease=blob.get('lease_id'),
139
+ if_modified_since=if_modified_since or blob.get('if_modified_since'),
140
+ if_unmodified_since=if_unmodified_since or blob.get('if_unmodified_since'),
141
+ etag=blob.get('etag'),
142
+ if_tags_match_condition=if_tags_match_condition or blob.get('if_tags_match_condition'),
143
+ match_condition=blob.get('match_condition') or MatchConditions.IfNotModified if blob.get('etag')
144
+ else None,
145
+ timeout=blob.get('timeout'),
146
+ )
147
+ else:
148
+ blob_name = blob
149
+ options = _generic_delete_blob_options( # pylint: disable=protected-access
150
+ delete_snapshots=delete_snapshots,
151
+ if_modified_since=if_modified_since,
152
+ if_unmodified_since=if_unmodified_since,
153
+ if_tags_match_condition=if_tags_match_condition
154
+ )
155
+
156
+ query_parameters, header_parameters = _generate_delete_blobs_subrequest_options(client, **options)
157
+
158
+ req = HttpRequest(
159
+ "DELETE",
160
+ f"/{quote(container_name)}/{quote(str(blob_name), safe='/~')}{query_str}",
161
+ headers=header_parameters
162
+ )
163
+ req.format_parameters(query_parameters)
164
+ reqs.append(req)
165
+
166
+ return reqs, kwargs
167
+
168
+ # This code is a copy from _generated.
169
+ # Once Autorest is able to provide request preparation this code should be removed.
170
+ def _generate_set_tiers_subrequest_options(
171
+ client: AzureBlobStorage,
172
+ tier: Optional[Union["PremiumPageBlobTier", "StandardBlobTier", str]],
173
+ snapshot: Optional[str] = None,
174
+ version_id: Optional[str] = None,
175
+ rehydrate_priority: Optional["RehydratePriority"] = None,
176
+ lease_access_conditions: Optional["LeaseAccessConditions"] = None,
177
+ **kwargs: Any
178
+ ) -> Tuple[Dict[str, Any], Dict[str, Any]]:
179
+ if not tier:
180
+ raise ValueError("A blob tier must be specified")
181
+ if snapshot and version_id:
182
+ raise ValueError("Snapshot and version_id cannot be set at the same time")
183
+ if_tags = kwargs.pop('if_tags', None)
184
+
185
+ lease_id = None
186
+ if lease_access_conditions is not None:
187
+ lease_id = lease_access_conditions.lease_id
188
+
189
+ comp = "tier"
190
+ timeout = kwargs.pop('timeout', None)
191
+ # Construct parameters
192
+ query_parameters = {}
193
+ if snapshot is not None:
194
+ query_parameters['snapshot'] = client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
195
+ if version_id is not None:
196
+ query_parameters['versionid'] = client._serialize.query("version_id", version_id, 'str') # pylint: disable=protected-access
197
+ if timeout is not None:
198
+ query_parameters['timeout'] = client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
199
+ query_parameters['comp'] = client._serialize.query("comp", comp, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
200
+
201
+ # Construct headers
202
+ header_parameters = {}
203
+ header_parameters['x-ms-access-tier'] = client._serialize.header("tier", tier, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
204
+ if rehydrate_priority is not None:
205
+ header_parameters['x-ms-rehydrate-priority'] = client._serialize.header( # pylint: disable=protected-access
206
+ "rehydrate_priority", rehydrate_priority, 'str')
207
+ if lease_id is not None:
208
+ header_parameters['x-ms-lease-id'] = client._serialize.header("lease_id", lease_id, 'str') # pylint: disable=protected-access
209
+ if if_tags is not None:
210
+ header_parameters['x-ms-if-tags'] = client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
211
+
212
+ return query_parameters, header_parameters
213
+
214
+ def _generate_set_tiers_options(
215
+ query_str: str,
216
+ container_name: str,
217
+ blob_tier: Optional[Union["PremiumPageBlobTier", "StandardBlobTier", str]],
218
+ client: AzureBlobStorage,
219
+ *blobs: Union[str, Dict[str, Any], BlobProperties],
220
+ **kwargs: Any
221
+ ) -> Tuple[List[HttpRequest], Dict[str, Any]]:
222
+ timeout = kwargs.pop('timeout', None)
223
+ raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
224
+ rehydrate_priority = kwargs.pop('rehydrate_priority', None)
225
+ if_tags = kwargs.pop('if_tags_match_condition', None)
226
+ kwargs.update({'raise_on_any_failure': raise_on_any_failure,
227
+ 'sas': query_str.replace('?', '&'),
228
+ 'timeout': '&timeout=' + str(timeout) if timeout else "",
229
+ 'path': container_name,
230
+ 'restype': 'restype=container&'
231
+ })
232
+
233
+ reqs = []
234
+ for blob in blobs:
235
+ if not isinstance(blob, str):
236
+ blob_name = blob.get('name')
237
+ tier = blob_tier or blob.get('blob_tier')
238
+ query_parameters, header_parameters = _generate_set_tiers_subrequest_options(
239
+ client=client,
240
+ tier=tier,
241
+ snapshot=blob.get('snapshot'),
242
+ version_id=blob.get('version_id'),
243
+ rehydrate_priority=rehydrate_priority or blob.get('rehydrate_priority'),
244
+ lease_access_conditions=blob.get('lease_id'),
245
+ if_tags=if_tags or blob.get('if_tags_match_condition'),
246
+ timeout=timeout or blob.get('timeout')
247
+ )
248
+ else:
249
+ blob_name = blob
250
+ query_parameters, header_parameters = _generate_set_tiers_subrequest_options(
251
+ client, blob_tier, rehydrate_priority=rehydrate_priority, if_tags=if_tags)
252
+
253
+ req = HttpRequest(
254
+ "PUT",
255
+ f"/{quote(container_name)}/{quote(str(blob_name), safe='/~')}{query_str}",
256
+ headers=header_parameters
257
+ )
258
+ req.format_parameters(query_parameters)
259
+ reqs.append(req)
260
+
261
+ return reqs, kwargs
@@ -4,10 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
 
7
- from typing import (
8
- Dict, List, Optional, Tuple, Union,
9
- TYPE_CHECKING
10
- )
7
+ from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING
11
8
  from urllib.parse import unquote
12
9
  from xml.etree.ElementTree import Element
13
10
 
@@ -25,16 +22,23 @@ from ._models import (
25
22
  ObjectReplicationPolicy,
26
23
  ObjectReplicationRule,
27
24
  RetentionPolicy,
28
- StaticWebsite,
25
+ StaticWebsite
29
26
  )
30
27
  from ._shared.models import get_enum_value
31
28
  from ._shared.response_handlers import deserialize_metadata
32
29
 
33
30
  if TYPE_CHECKING:
34
- from ._generated.models import BlobTag, PageList
35
-
31
+ from azure.core.pipeline import PipelineResponse
32
+ from ._generated.models import (
33
+ BlobItemInternal,
34
+ BlobTags,
35
+ PageList,
36
+ StorageServiceProperties,
37
+ StorageServiceStats,
38
+ )
39
+ from ._shared.models import LocationMode
36
40
 
37
- def deserialize_pipeline_response_into_cls(cls_method, response, obj, headers):
41
+ def deserialize_pipeline_response_into_cls(cls_method, response: "PipelineResponse", obj: Any, headers: Dict[str, Any]):
38
42
  try:
39
43
  deserialized_response = response.http_response
40
44
  except AttributeError:
@@ -42,7 +46,7 @@ def deserialize_pipeline_response_into_cls(cls_method, response, obj, headers):
42
46
  return cls_method(deserialized_response, obj, headers)
43
47
 
44
48
 
45
- def deserialize_blob_properties(response, obj, headers):
49
+ def deserialize_blob_properties(response: "PipelineResponse", obj: Any, headers: Dict[str, Any]) -> BlobProperties:
46
50
  blob_properties = BlobProperties(
47
51
  metadata=deserialize_metadata(response, obj, headers),
48
52
  object_replication_source_properties=deserialize_ors_policies(response.http_response.headers),
@@ -56,7 +60,7 @@ def deserialize_blob_properties(response, obj, headers):
56
60
  return blob_properties
57
61
 
58
62
 
59
- def deserialize_ors_policies(policy_dictionary):
63
+ def deserialize_ors_policies(policy_dictionary: Optional[Dict[str, str]]) -> Optional[List[ObjectReplicationPolicy]]:
60
64
 
61
65
  if policy_dictionary is None:
62
66
  return None
@@ -66,7 +70,7 @@ def deserialize_ors_policies(policy_dictionary):
66
70
  or_policy_status_headers = {key: val for key, val in policy_dictionary.items()
67
71
  if 'or-' in key and key != 'x-ms-or-policy-id'}
68
72
 
69
- parsed_result = {}
73
+ parsed_result: Dict[str, List[ObjectReplicationRule]] = {}
70
74
 
71
75
  for key, val in or_policy_status_headers.items():
72
76
  # list blobs gives or-policy_rule and get blob properties gives x-ms-or-policy_rule
@@ -83,13 +87,21 @@ def deserialize_ors_policies(policy_dictionary):
83
87
  return result_list
84
88
 
85
89
 
86
- def deserialize_blob_stream(response, obj, headers):
90
+ def deserialize_blob_stream(
91
+ response: "PipelineResponse",
92
+ obj: Any,
93
+ headers: Dict[str, Any]
94
+ ) -> Tuple["LocationMode", Any]:
87
95
  blob_properties = deserialize_blob_properties(response, obj, headers)
88
96
  obj.properties = blob_properties
89
97
  return response.http_response.location_mode, obj
90
98
 
91
99
 
92
- def deserialize_container_properties(response, obj, headers):
100
+ def deserialize_container_properties(
101
+ response: "PipelineResponse",
102
+ obj: Any,
103
+ headers: Dict[str, Any]
104
+ ) -> ContainerProperties:
93
105
  metadata = deserialize_metadata(response, obj, headers)
94
106
  container_properties = ContainerProperties(
95
107
  metadata=metadata,
@@ -98,65 +110,70 @@ def deserialize_container_properties(response, obj, headers):
98
110
  return container_properties
99
111
 
100
112
 
101
- def get_page_ranges_result(ranges):
102
- # type: (PageList) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
103
- page_range = [] # type: ignore
104
- clear_range = [] # type: List
113
+ def get_page_ranges_result(ranges: "PageList") -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]:
114
+ page_range = []
115
+ clear_range = []
105
116
  if ranges.page_range:
106
- page_range = [{'start': b.start, 'end': b.end} for b in ranges.page_range] # type: ignore
117
+ page_range = [{'start': b.start, 'end': b.end} for b in ranges.page_range]
107
118
  if ranges.clear_range:
108
119
  clear_range = [{'start': b.start, 'end': b.end} for b in ranges.clear_range]
109
- return page_range, clear_range # type: ignore
120
+ return page_range, clear_range
110
121
 
111
122
 
112
- # Deserialize a ServiceStats objects into a dict.
113
- def service_stats_deserialize(generated):
123
+ def service_stats_deserialize(generated: "StorageServiceStats") -> Dict[str, Any]:
124
+ status = None
125
+ last_sync_time = None
126
+ if generated.geo_replication is not None:
127
+ status = generated.geo_replication.status
128
+ last_sync_time = generated.geo_replication.last_sync_time
114
129
  return {
115
130
  'geo_replication': {
116
- 'status': generated.geo_replication.status,
117
- 'last_sync_time': generated.geo_replication.last_sync_time,
131
+ 'status': status,
132
+ 'last_sync_time': last_sync_time
118
133
  }
119
134
  }
120
135
 
121
- # Deserialize a ServiceProperties objects into a dict.
122
- def service_properties_deserialize(generated):
136
+ def service_properties_deserialize(generated: "StorageServiceProperties") -> Dict[str, Any]:
137
+ cors_list = None
138
+ if generated.cors is not None:
139
+ cors_list = [CorsRule._from_generated(cors) for cors in generated.cors] # pylint: disable=protected-access
123
140
  return {
124
141
  'analytics_logging': BlobAnalyticsLogging._from_generated(generated.logging), # pylint: disable=protected-access
125
142
  'hour_metrics': Metrics._from_generated(generated.hour_metrics), # pylint: disable=protected-access
126
143
  'minute_metrics': Metrics._from_generated(generated.minute_metrics), # pylint: disable=protected-access
127
- 'cors': [CorsRule._from_generated(cors) for cors in generated.cors], # pylint: disable=protected-access
144
+ 'cors': cors_list,
128
145
  'target_version': generated.default_service_version, # pylint: disable=protected-access
129
146
  'delete_retention_policy': RetentionPolicy._from_generated(generated.delete_retention_policy), # pylint: disable=protected-access
130
147
  'static_website': StaticWebsite._from_generated(generated.static_website), # pylint: disable=protected-access
131
148
  }
132
149
 
133
150
 
134
- def get_blob_properties_from_generated_code(generated):
151
+ def get_blob_properties_from_generated_code(generated: "BlobItemInternal") -> BlobProperties:
135
152
  blob = BlobProperties()
136
- if generated.name.encoded:
153
+ if generated.name.encoded and generated.name.content is not None:
137
154
  blob.name = unquote(generated.name.content)
138
155
  else:
139
- blob.name = generated.name.content
156
+ blob.name = generated.name.content #type: ignore
140
157
  blob_type = get_enum_value(generated.properties.blob_type)
141
- blob.blob_type = BlobType(blob_type) if blob_type else None
158
+ blob.blob_type = BlobType(blob_type)
142
159
  blob.etag = generated.properties.etag
143
160
  blob.deleted = generated.deleted
144
161
  blob.snapshot = generated.snapshot
145
162
  blob.is_append_blob_sealed = generated.properties.is_sealed
146
- blob.metadata = generated.metadata.additional_properties if generated.metadata else {}
163
+ blob.metadata = generated.metadata.additional_properties if generated.metadata else {} # type: ignore [assignment]
147
164
  blob.encrypted_metadata = generated.metadata.encrypted if generated.metadata else None
148
165
  blob.lease = LeaseProperties._from_generated(generated) # pylint: disable=protected-access
149
166
  blob.copy = CopyProperties._from_generated(generated) # pylint: disable=protected-access
150
167
  blob.last_modified = generated.properties.last_modified
151
- blob.creation_time = generated.properties.creation_time
168
+ blob.creation_time = generated.properties.creation_time # type: ignore [assignment]
152
169
  blob.content_settings = ContentSettings._from_generated(generated) # pylint: disable=protected-access
153
- blob.size = generated.properties.content_length
170
+ blob.size = generated.properties.content_length # type: ignore [assignment]
154
171
  blob.page_blob_sequence_number = generated.properties.blob_sequence_number
155
- blob.server_encrypted = generated.properties.server_encrypted
172
+ blob.server_encrypted = generated.properties.server_encrypted # type: ignore [assignment]
156
173
  blob.encryption_scope = generated.properties.encryption_scope
157
174
  blob.deleted_time = generated.properties.deleted_time
158
175
  blob.remaining_retention_days = generated.properties.remaining_retention_days
159
- blob.blob_tier = generated.properties.access_tier
176
+ blob.blob_tier = generated.properties.access_tier # type: ignore [assignment]
160
177
  blob.rehydrate_priority = generated.properties.rehydrate_priority
161
178
  blob.blob_tier_inferred = generated.properties.access_tier_inferred
162
179
  blob.archive_status = generated.properties.archive_status
@@ -172,13 +189,13 @@ def get_blob_properties_from_generated_code(generated):
172
189
  blob.has_versions_only = generated.has_versions_only
173
190
  return blob
174
191
 
175
- def parse_tags(generated_tags: Optional[List["BlobTag"]]) -> Union[Dict[str, str], None]:
192
+ def parse_tags(generated_tags: Optional["BlobTags"]) -> Optional[Dict[str, str]]:
176
193
  """Deserialize a list of BlobTag objects into a dict.
177
194
 
178
- :param Optional[List[BlobTag]] generated_tags:
195
+ :param Optional[BlobTags] generated_tags:
179
196
  A list containing the BlobTag objects from generated code.
180
197
  :returns: A dictionary of the BlobTag objects.
181
- :rtype: Dict[str, str] or None
198
+ :rtype: Optional[Dict[str, str]]
182
199
  """
183
200
  if generated_tags:
184
201
  tag_dict = {t.key: t.value for t in generated_tags.blob_tag_set}
@@ -186,24 +203,31 @@ def parse_tags(generated_tags: Optional[List["BlobTag"]]) -> Union[Dict[str, str
186
203
  return None
187
204
 
188
205
 
189
- def load_single_xml_node(element: Element, name: str) -> Union[Element, None]:
206
+ def load_single_xml_node(element: Element, name: str) -> Optional[Element]:
190
207
  return element.find(name)
191
208
 
192
209
 
193
- def load_many_xml_nodes(element: Element, name: str, wrapper: Element = None) -> List[Union[Element, None]]:
210
+ def load_many_xml_nodes(
211
+ element: Element,
212
+ name: str,
213
+ wrapper: Optional[str] = None
214
+ ) -> List[Optional[Element]]:
215
+ found_element: Optional[Element] = element
194
216
  if wrapper:
195
- element = load_single_xml_node(element, wrapper)
196
- return list(element.findall(name))
217
+ found_element = load_single_xml_node(element, wrapper)
218
+ if found_element is None:
219
+ return []
220
+ return list(found_element.findall(name))
197
221
 
198
222
 
199
- def load_xml_string(element: Element, name: str) -> str:
223
+ def load_xml_string(element: Element, name: str) -> Optional[str]:
200
224
  node = element.find(name)
201
225
  if node is None or not node.text:
202
226
  return None
203
227
  return node.text
204
228
 
205
229
 
206
- def load_xml_int(element: Element, name: str) -> int:
230
+ def load_xml_int(element: Element, name: str) -> Optional[int]:
207
231
  node = element.find(name)
208
232
  if node is None or not node.text:
209
233
  return None