azure-storage-blob 12.19.1__py3-none-any.whl → 12.20.0b1__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 +7 -5
- azure/storage/blob/_blob_client.py +12 -4
- azure/storage/blob/_blob_service_client.py +4 -3
- azure/storage/blob/_container_client.py +28 -12
- azure/storage/blob/_download.py +3 -3
- azure/storage/blob/_encryption.py +254 -165
- azure/storage/blob/_generated/_azure_blob_storage.py +21 -3
- azure/storage/blob/_generated/_configuration.py +4 -11
- azure/storage/blob/_generated/_serialization.py +41 -49
- azure/storage/blob/_generated/aio/_azure_blob_storage.py +23 -3
- azure/storage/blob/_generated/aio/_configuration.py +4 -11
- azure/storage/blob/_generated/aio/operations/_append_blob_operations.py +24 -58
- azure/storage/blob/_generated/aio/operations/_blob_operations.py +123 -306
- azure/storage/blob/_generated/aio/operations/_block_blob_operations.py +37 -86
- azure/storage/blob/_generated/aio/operations/_container_operations.py +98 -289
- azure/storage/blob/_generated/aio/operations/_page_blob_operations.py +51 -150
- azure/storage/blob/_generated/aio/operations/_service_operations.py +49 -125
- azure/storage/blob/_generated/models/_models_py3.py +31 -31
- azure/storage/blob/_generated/operations/_append_blob_operations.py +25 -59
- azure/storage/blob/_generated/operations/_blob_operations.py +123 -306
- azure/storage/blob/_generated/operations/_block_blob_operations.py +39 -88
- azure/storage/blob/_generated/operations/_container_operations.py +100 -291
- azure/storage/blob/_generated/operations/_page_blob_operations.py +52 -151
- azure/storage/blob/_generated/operations/_service_operations.py +50 -126
- azure/storage/blob/_models.py +3 -4
- azure/storage/blob/_serialize.py +1 -0
- azure/storage/blob/_shared/authentication.py +1 -1
- azure/storage/blob/_shared/avro/avro_io.py +0 -6
- azure/storage/blob/_shared/avro/avro_io_async.py +0 -6
- azure/storage/blob/_shared/avro/datafile.py +0 -4
- azure/storage/blob/_shared/avro/datafile_async.py +0 -4
- azure/storage/blob/_shared/avro/schema.py +4 -4
- azure/storage/blob/_shared/base_client.py +72 -87
- azure/storage/blob/_shared/base_client_async.py +115 -27
- azure/storage/blob/_shared/models.py +112 -20
- azure/storage/blob/_shared/parser.py +7 -6
- azure/storage/blob/_shared/policies.py +96 -66
- azure/storage/blob/_shared/policies_async.py +48 -21
- azure/storage/blob/_shared/response_handlers.py +14 -16
- azure/storage/blob/_shared/shared_access_signature.py +2 -3
- azure/storage/blob/_shared_access_signature.py +37 -27
- azure/storage/blob/_upload_helpers.py +4 -7
- azure/storage/blob/_version.py +1 -1
- azure/storage/blob/aio/__init__.py +2 -2
- azure/storage/blob/aio/_blob_client_async.py +16 -5
- azure/storage/blob/aio/_blob_service_client_async.py +3 -1
- azure/storage/blob/aio/_container_client_async.py +25 -8
- azure/storage/blob/aio/_download_async.py +9 -9
- azure/storage/blob/aio/_encryption_async.py +72 -0
- azure/storage/blob/aio/_upload_helpers.py +8 -10
- {azure_storage_blob-12.19.1.dist-info → azure_storage_blob-12.20.0b1.dist-info}/METADATA +9 -9
- azure_storage_blob-12.20.0b1.dist-info/RECORD +81 -0
- {azure_storage_blob-12.19.1.dist-info → azure_storage_blob-12.20.0b1.dist-info}/WHEEL +1 -1
- azure/storage/blob/_generated/py.typed +0 -1
- azure_storage_blob-12.19.1.dist-info/RECORD +0 -81
- {azure_storage_blob-12.19.1.dist-info → azure_storage_blob-12.20.0b1.dist-info}/LICENSE +0 -0
- {azure_storage_blob-12.19.1.dist-info → azure_storage_blob-12.20.0b1.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,7 @@ from copy import deepcopy
|
|
10
10
|
from typing import Any
|
11
11
|
|
12
12
|
from azure.core import PipelineClient
|
13
|
+
from azure.core.pipeline import policies
|
13
14
|
from azure.core.rest import HttpRequest, HttpResponse
|
14
15
|
|
15
16
|
from . import models as _models
|
@@ -54,7 +55,24 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
54
55
|
self, url: str, base_url: str = "", **kwargs: Any
|
55
56
|
) -> None:
|
56
57
|
self._config = AzureBlobStorageConfiguration(url=url, **kwargs)
|
57
|
-
|
58
|
+
_policies = kwargs.pop("policies", None)
|
59
|
+
if _policies is None:
|
60
|
+
_policies = [
|
61
|
+
policies.RequestIdPolicy(**kwargs),
|
62
|
+
self._config.headers_policy,
|
63
|
+
self._config.user_agent_policy,
|
64
|
+
self._config.proxy_policy,
|
65
|
+
policies.ContentDecodePolicy(**kwargs),
|
66
|
+
self._config.redirect_policy,
|
67
|
+
self._config.retry_policy,
|
68
|
+
self._config.authentication_policy,
|
69
|
+
self._config.custom_hook_policy,
|
70
|
+
self._config.logging_policy,
|
71
|
+
policies.DistributedTracingPolicy(**kwargs),
|
72
|
+
policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,
|
73
|
+
self._config.http_logging_policy,
|
74
|
+
]
|
75
|
+
self._client: PipelineClient = PipelineClient(base_url=base_url, policies=_policies, **kwargs)
|
58
76
|
|
59
77
|
client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)}
|
60
78
|
self._serialize = Serializer(client_models)
|
@@ -67,7 +85,7 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
67
85
|
self.append_blob = AppendBlobOperations(self._client, self._config, self._serialize, self._deserialize)
|
68
86
|
self.block_blob = BlockBlobOperations(self._client, self._config, self._serialize, self._deserialize)
|
69
87
|
|
70
|
-
def _send_request(self, request: HttpRequest, **kwargs: Any) -> HttpResponse:
|
88
|
+
def _send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse:
|
71
89
|
"""Runs the network request through the client's chained policies.
|
72
90
|
|
73
91
|
>>> from azure.core.rest import HttpRequest
|
@@ -87,7 +105,7 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
87
105
|
|
88
106
|
request_copy = deepcopy(request)
|
89
107
|
request_copy.url = self._client.format_url(request_copy.url)
|
90
|
-
return self._client.send_request(request_copy, **kwargs)
|
108
|
+
return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore
|
91
109
|
|
92
110
|
def close(self) -> None:
|
93
111
|
self._client.close()
|
@@ -6,21 +6,14 @@
|
|
6
6
|
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
7
7
|
# --------------------------------------------------------------------------
|
8
8
|
|
9
|
-
import
|
10
|
-
from typing import Any
|
9
|
+
from typing import Any, Literal
|
11
10
|
|
12
|
-
from azure.core.configuration import Configuration
|
13
11
|
from azure.core.pipeline import policies
|
14
12
|
|
15
|
-
if sys.version_info >= (3, 8):
|
16
|
-
from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
|
17
|
-
else:
|
18
|
-
from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports
|
19
|
-
|
20
13
|
VERSION = "unknown"
|
21
14
|
|
22
15
|
|
23
|
-
class AzureBlobStorageConfiguration
|
16
|
+
class AzureBlobStorageConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long
|
24
17
|
"""Configuration for AzureBlobStorage.
|
25
18
|
|
26
19
|
Note that all parameters used to create this instance are saved as instance
|
@@ -35,7 +28,6 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
35
28
|
"""
|
36
29
|
|
37
30
|
def __init__(self, url: str, **kwargs: Any) -> None:
|
38
|
-
super(AzureBlobStorageConfiguration, self).__init__(**kwargs)
|
39
31
|
version: Literal["2021-12-02"] = kwargs.pop("version", "2021-12-02")
|
40
32
|
|
41
33
|
if url is None:
|
@@ -44,6 +36,7 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
44
36
|
self.url = url
|
45
37
|
self.version = version
|
46
38
|
kwargs.setdefault("sdk_moniker", "azureblobstorage/{}".format(VERSION))
|
39
|
+
self.polling_interval = kwargs.get("polling_interval", 30)
|
47
40
|
self._configure(**kwargs)
|
48
41
|
|
49
42
|
def _configure(self, **kwargs: Any) -> None:
|
@@ -52,7 +45,7 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
52
45
|
self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs)
|
53
46
|
self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs)
|
54
47
|
self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs)
|
55
|
-
self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs)
|
56
48
|
self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs)
|
57
49
|
self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs)
|
50
|
+
self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs)
|
58
51
|
self.authentication_policy = kwargs.get("authentication_policy")
|
@@ -63,8 +63,8 @@ import xml.etree.ElementTree as ET
|
|
63
63
|
|
64
64
|
import isodate # type: ignore
|
65
65
|
|
66
|
-
from azure.core.exceptions import DeserializationError, SerializationError
|
67
|
-
from azure.core.serialization import NULL as
|
66
|
+
from azure.core.exceptions import DeserializationError, SerializationError
|
67
|
+
from azure.core.serialization import NULL as CoreNull
|
68
68
|
|
69
69
|
_BOM = codecs.BOM_UTF8.decode(encoding="utf-8")
|
70
70
|
|
@@ -124,7 +124,7 @@ class RawDeserializer:
|
|
124
124
|
pass
|
125
125
|
|
126
126
|
return ET.fromstring(data_as_str) # nosec
|
127
|
-
except ET.ParseError:
|
127
|
+
except ET.ParseError as err:
|
128
128
|
# It might be because the server has an issue, and returned JSON with
|
129
129
|
# content-type XML....
|
130
130
|
# So let's try a JSON load, and if it's still broken
|
@@ -143,7 +143,7 @@ class RawDeserializer:
|
|
143
143
|
# The function hack is because Py2.7 messes up with exception
|
144
144
|
# context otherwise.
|
145
145
|
_LOGGER.critical("Wasn't XML not JSON, failing")
|
146
|
-
|
146
|
+
raise DeserializationError("XML is invalid") from err
|
147
147
|
raise DeserializationError("Cannot deserialize content-type: {}".format(content_type))
|
148
148
|
|
149
149
|
@classmethod
|
@@ -170,13 +170,6 @@ class RawDeserializer:
|
|
170
170
|
return None
|
171
171
|
|
172
172
|
|
173
|
-
try:
|
174
|
-
basestring # type: ignore
|
175
|
-
unicode_str = unicode # type: ignore
|
176
|
-
except NameError:
|
177
|
-
basestring = str
|
178
|
-
unicode_str = str
|
179
|
-
|
180
173
|
_LOGGER = logging.getLogger(__name__)
|
181
174
|
|
182
175
|
try:
|
@@ -295,7 +288,7 @@ class Model(object):
|
|
295
288
|
_validation: Dict[str, Dict[str, Any]] = {}
|
296
289
|
|
297
290
|
def __init__(self, **kwargs: Any) -> None:
|
298
|
-
self.additional_properties: Dict[str, Any] = {}
|
291
|
+
self.additional_properties: Optional[Dict[str, Any]] = {}
|
299
292
|
for k in kwargs:
|
300
293
|
if k not in self._attribute_map:
|
301
294
|
_LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__)
|
@@ -340,7 +333,7 @@ class Model(object):
|
|
340
333
|
return _create_xml_node(xml_map.get("name", cls.__name__), xml_map.get("prefix", None), xml_map.get("ns", None))
|
341
334
|
|
342
335
|
def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON:
|
343
|
-
"""Return the JSON that would be sent to
|
336
|
+
"""Return the JSON that would be sent to server from this model.
|
344
337
|
|
345
338
|
This is an alias to `as_dict(full_restapi_key_transformer, keep_readonly=False)`.
|
346
339
|
|
@@ -351,7 +344,7 @@ class Model(object):
|
|
351
344
|
:rtype: dict
|
352
345
|
"""
|
353
346
|
serializer = Serializer(self._infer_class_models())
|
354
|
-
return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs)
|
347
|
+
return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) # type: ignore
|
355
348
|
|
356
349
|
def as_dict(
|
357
350
|
self,
|
@@ -390,7 +383,7 @@ class Model(object):
|
|
390
383
|
:rtype: dict
|
391
384
|
"""
|
392
385
|
serializer = Serializer(self._infer_class_models())
|
393
|
-
return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs)
|
386
|
+
return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) # type: ignore
|
394
387
|
|
395
388
|
@classmethod
|
396
389
|
def _infer_class_models(cls):
|
@@ -415,7 +408,7 @@ class Model(object):
|
|
415
408
|
:raises: DeserializationError if something went wrong
|
416
409
|
"""
|
417
410
|
deserializer = Deserializer(cls._infer_class_models())
|
418
|
-
return deserializer(cls.__name__, data, content_type=content_type)
|
411
|
+
return deserializer(cls.__name__, data, content_type=content_type) # type: ignore
|
419
412
|
|
420
413
|
@classmethod
|
421
414
|
def from_dict(
|
@@ -445,7 +438,7 @@ class Model(object):
|
|
445
438
|
if key_extractors is None
|
446
439
|
else key_extractors
|
447
440
|
)
|
448
|
-
return deserializer(cls.__name__, data, content_type=content_type)
|
441
|
+
return deserializer(cls.__name__, data, content_type=content_type) # type: ignore
|
449
442
|
|
450
443
|
@classmethod
|
451
444
|
def _flatten_subtype(cls, key, objects):
|
@@ -545,7 +538,7 @@ class Serializer(object):
|
|
545
538
|
"multiple": lambda x, y: x % y != 0,
|
546
539
|
}
|
547
540
|
|
548
|
-
def __init__(self, classes: Optional[Mapping[str,
|
541
|
+
def __init__(self, classes: Optional[Mapping[str, type]] = None):
|
549
542
|
self.serialize_type = {
|
550
543
|
"iso-8601": Serializer.serialize_iso,
|
551
544
|
"rfc-1123": Serializer.serialize_rfc,
|
@@ -561,7 +554,7 @@ class Serializer(object):
|
|
561
554
|
"[]": self.serialize_iter,
|
562
555
|
"{}": self.serialize_dict,
|
563
556
|
}
|
564
|
-
self.dependencies: Dict[str,
|
557
|
+
self.dependencies: Dict[str, type] = dict(classes) if classes else {}
|
565
558
|
self.key_transformer = full_restapi_key_transformer
|
566
559
|
self.client_side_validation = True
|
567
560
|
|
@@ -649,7 +642,7 @@ class Serializer(object):
|
|
649
642
|
else: # That's a basic type
|
650
643
|
# Integrate namespace if necessary
|
651
644
|
local_node = _create_xml_node(xml_name, xml_prefix, xml_ns)
|
652
|
-
local_node.text =
|
645
|
+
local_node.text = str(new_attr)
|
653
646
|
serialized.append(local_node) # type: ignore
|
654
647
|
else: # JSON
|
655
648
|
for k in reversed(keys): # type: ignore
|
@@ -668,7 +661,7 @@ class Serializer(object):
|
|
668
661
|
|
669
662
|
except (AttributeError, KeyError, TypeError) as err:
|
670
663
|
msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj))
|
671
|
-
|
664
|
+
raise SerializationError(msg) from err
|
672
665
|
else:
|
673
666
|
return serialized
|
674
667
|
|
@@ -710,7 +703,7 @@ class Serializer(object):
|
|
710
703
|
]
|
711
704
|
data = deserializer._deserialize(data_type, data)
|
712
705
|
except DeserializationError as err:
|
713
|
-
|
706
|
+
raise SerializationError("Unable to build a model: " + str(err)) from err
|
714
707
|
|
715
708
|
return self._serialize(data, data_type, **kwargs)
|
716
709
|
|
@@ -730,6 +723,7 @@ class Serializer(object):
|
|
730
723
|
|
731
724
|
if kwargs.get("skip_quote") is True:
|
732
725
|
output = str(output)
|
726
|
+
output = output.replace("{", quote("{")).replace("}", quote("}"))
|
733
727
|
else:
|
734
728
|
output = quote(str(output), safe="")
|
735
729
|
except SerializationError:
|
@@ -744,7 +738,7 @@ class Serializer(object):
|
|
744
738
|
:param str data_type: The type to be serialized from.
|
745
739
|
:keyword bool skip_quote: Whether to skip quote the serialized result.
|
746
740
|
Defaults to False.
|
747
|
-
:rtype: str
|
741
|
+
:rtype: str, list
|
748
742
|
:raises: TypeError if serialization fails.
|
749
743
|
:raises: ValueError if data is None
|
750
744
|
"""
|
@@ -753,7 +747,7 @@ class Serializer(object):
|
|
753
747
|
if data_type.startswith("["):
|
754
748
|
internal_data_type = data_type[1:-1]
|
755
749
|
do_quote = not kwargs.get("skip_quote", False)
|
756
|
-
return
|
750
|
+
return self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs)
|
757
751
|
|
758
752
|
# Not a list, regular serialization
|
759
753
|
output = self.serialize_data(data, data_type, **kwargs)
|
@@ -804,7 +798,7 @@ class Serializer(object):
|
|
804
798
|
raise ValueError("No value for given attribute")
|
805
799
|
|
806
800
|
try:
|
807
|
-
if data is
|
801
|
+
if data is CoreNull:
|
808
802
|
return None
|
809
803
|
if data_type in self.basic_types.values():
|
810
804
|
return self.serialize_basic(data, data_type, **kwargs)
|
@@ -824,7 +818,7 @@ class Serializer(object):
|
|
824
818
|
|
825
819
|
except (ValueError, TypeError) as err:
|
826
820
|
msg = "Unable to serialize value: {!r} as type: {!r}."
|
827
|
-
|
821
|
+
raise SerializationError(msg.format(data, data_type)) from err
|
828
822
|
else:
|
829
823
|
return self._serialize(data, **kwargs)
|
830
824
|
|
@@ -993,7 +987,7 @@ class Serializer(object):
|
|
993
987
|
return self.serialize_basic(attr, self.basic_types[obj_type], **kwargs)
|
994
988
|
if obj_type is _long_type:
|
995
989
|
return self.serialize_long(attr)
|
996
|
-
if obj_type is
|
990
|
+
if obj_type is str:
|
997
991
|
return self.serialize_unicode(attr)
|
998
992
|
if obj_type is datetime.datetime:
|
999
993
|
return self.serialize_iso(attr)
|
@@ -1170,10 +1164,10 @@ class Serializer(object):
|
|
1170
1164
|
return date + microseconds + "Z"
|
1171
1165
|
except (ValueError, OverflowError) as err:
|
1172
1166
|
msg = "Unable to serialize datetime object."
|
1173
|
-
|
1167
|
+
raise SerializationError(msg) from err
|
1174
1168
|
except AttributeError as err:
|
1175
1169
|
msg = "ISO-8601 object must be valid Datetime object."
|
1176
|
-
|
1170
|
+
raise TypeError(msg) from err
|
1177
1171
|
|
1178
1172
|
@staticmethod
|
1179
1173
|
def serialize_unix(attr, **kwargs):
|
@@ -1209,7 +1203,6 @@ def rest_key_extractor(attr, attr_desc, data):
|
|
1209
1203
|
if working_data is None:
|
1210
1204
|
# If at any point while following flatten JSON path see None, it means
|
1211
1205
|
# that all properties under are None as well
|
1212
|
-
# https://github.com/Azure/msrest-for-python/issues/197
|
1213
1206
|
return None
|
1214
1207
|
key = ".".join(dict_keys[1:])
|
1215
1208
|
|
@@ -1230,7 +1223,6 @@ def rest_key_case_insensitive_extractor(attr, attr_desc, data):
|
|
1230
1223
|
if working_data is None:
|
1231
1224
|
# If at any point while following flatten JSON path see None, it means
|
1232
1225
|
# that all properties under are None as well
|
1233
|
-
# https://github.com/Azure/msrest-for-python/issues/197
|
1234
1226
|
return None
|
1235
1227
|
key = ".".join(dict_keys[1:])
|
1236
1228
|
|
@@ -1371,7 +1363,7 @@ class Deserializer(object):
|
|
1371
1363
|
|
1372
1364
|
valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?")
|
1373
1365
|
|
1374
|
-
def __init__(self, classes: Optional[Mapping[str,
|
1366
|
+
def __init__(self, classes: Optional[Mapping[str, type]] = None):
|
1375
1367
|
self.deserialize_type = {
|
1376
1368
|
"iso-8601": Deserializer.deserialize_iso,
|
1377
1369
|
"rfc-1123": Deserializer.deserialize_rfc,
|
@@ -1391,7 +1383,7 @@ class Deserializer(object):
|
|
1391
1383
|
"duration": (isodate.Duration, datetime.timedelta),
|
1392
1384
|
"iso-8601": (datetime.datetime),
|
1393
1385
|
}
|
1394
|
-
self.dependencies: Dict[str,
|
1386
|
+
self.dependencies: Dict[str, type] = dict(classes) if classes else {}
|
1395
1387
|
self.key_extractors = [rest_key_extractor, xml_key_extractor]
|
1396
1388
|
# Additional properties only works if the "rest_key_extractor" is used to
|
1397
1389
|
# extract the keys. Making it to work whatever the key extractor is too much
|
@@ -1444,7 +1436,7 @@ class Deserializer(object):
|
|
1444
1436
|
|
1445
1437
|
response, class_name = self._classify_target(target_obj, data)
|
1446
1438
|
|
1447
|
-
if isinstance(response,
|
1439
|
+
if isinstance(response, str):
|
1448
1440
|
return self.deserialize_data(data, response)
|
1449
1441
|
elif isinstance(response, type) and issubclass(response, Enum):
|
1450
1442
|
return self.deserialize_enum(data, response)
|
@@ -1481,7 +1473,7 @@ class Deserializer(object):
|
|
1481
1473
|
d_attrs[attr] = value
|
1482
1474
|
except (AttributeError, TypeError, KeyError) as err:
|
1483
1475
|
msg = "Unable to deserialize to object: " + class_name # type: ignore
|
1484
|
-
|
1476
|
+
raise DeserializationError(msg) from err
|
1485
1477
|
else:
|
1486
1478
|
additional_properties = self._build_additional_properties(attributes, data)
|
1487
1479
|
return self._instantiate_model(response, d_attrs, additional_properties)
|
@@ -1515,14 +1507,14 @@ class Deserializer(object):
|
|
1515
1507
|
if target is None:
|
1516
1508
|
return None, None
|
1517
1509
|
|
1518
|
-
if isinstance(target,
|
1510
|
+
if isinstance(target, str):
|
1519
1511
|
try:
|
1520
1512
|
target = self.dependencies[target]
|
1521
1513
|
except KeyError:
|
1522
1514
|
return target, target
|
1523
1515
|
|
1524
1516
|
try:
|
1525
|
-
target = target._classify(data, self.dependencies)
|
1517
|
+
target = target._classify(data, self.dependencies) # type: ignore
|
1526
1518
|
except AttributeError:
|
1527
1519
|
pass # Target is not a Model, no classify
|
1528
1520
|
return target, target.__class__.__name__ # type: ignore
|
@@ -1578,7 +1570,7 @@ class Deserializer(object):
|
|
1578
1570
|
if hasattr(raw_data, "_content_consumed"):
|
1579
1571
|
return RawDeserializer.deserialize_from_http_generics(raw_data.text, raw_data.headers)
|
1580
1572
|
|
1581
|
-
if isinstance(raw_data, (
|
1573
|
+
if isinstance(raw_data, (str, bytes)) or hasattr(raw_data, "read"):
|
1582
1574
|
return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore
|
1583
1575
|
return raw_data
|
1584
1576
|
|
@@ -1652,7 +1644,7 @@ class Deserializer(object):
|
|
1652
1644
|
except (ValueError, TypeError, AttributeError) as err:
|
1653
1645
|
msg = "Unable to deserialize response data."
|
1654
1646
|
msg += " Data: {}, {}".format(data, data_type)
|
1655
|
-
|
1647
|
+
raise DeserializationError(msg) from err
|
1656
1648
|
else:
|
1657
1649
|
return self._deserialize(obj_type, data)
|
1658
1650
|
|
@@ -1700,7 +1692,7 @@ class Deserializer(object):
|
|
1700
1692
|
if isinstance(attr, ET.Element):
|
1701
1693
|
# Do no recurse on XML, just return the tree as-is
|
1702
1694
|
return attr
|
1703
|
-
if isinstance(attr,
|
1695
|
+
if isinstance(attr, str):
|
1704
1696
|
return self.deserialize_basic(attr, "str")
|
1705
1697
|
obj_type = type(attr)
|
1706
1698
|
if obj_type in self.basic_types:
|
@@ -1757,7 +1749,7 @@ class Deserializer(object):
|
|
1757
1749
|
if data_type == "bool":
|
1758
1750
|
if attr in [True, False, 1, 0]:
|
1759
1751
|
return bool(attr)
|
1760
|
-
elif isinstance(attr,
|
1752
|
+
elif isinstance(attr, str):
|
1761
1753
|
if attr.lower() in ["true", "1"]:
|
1762
1754
|
return True
|
1763
1755
|
elif attr.lower() in ["false", "0"]:
|
@@ -1808,7 +1800,6 @@ class Deserializer(object):
|
|
1808
1800
|
data = data.value
|
1809
1801
|
if isinstance(data, int):
|
1810
1802
|
# Workaround. We might consider remove it in the future.
|
1811
|
-
# https://github.com/Azure/azure-rest-api-specs/issues/141
|
1812
1803
|
try:
|
1813
1804
|
return list(enum_obj.__members__.values())[data]
|
1814
1805
|
except IndexError:
|
@@ -1862,10 +1853,10 @@ class Deserializer(object):
|
|
1862
1853
|
if isinstance(attr, ET.Element):
|
1863
1854
|
attr = attr.text
|
1864
1855
|
try:
|
1865
|
-
return decimal.Decimal(attr) # type: ignore
|
1856
|
+
return decimal.Decimal(str(attr)) # type: ignore
|
1866
1857
|
except decimal.DecimalException as err:
|
1867
1858
|
msg = "Invalid decimal {}".format(attr)
|
1868
|
-
|
1859
|
+
raise DeserializationError(msg) from err
|
1869
1860
|
|
1870
1861
|
@staticmethod
|
1871
1862
|
def deserialize_long(attr):
|
@@ -1893,7 +1884,7 @@ class Deserializer(object):
|
|
1893
1884
|
duration = isodate.parse_duration(attr)
|
1894
1885
|
except (ValueError, OverflowError, AttributeError) as err:
|
1895
1886
|
msg = "Cannot deserialize duration object."
|
1896
|
-
|
1887
|
+
raise DeserializationError(msg) from err
|
1897
1888
|
else:
|
1898
1889
|
return duration
|
1899
1890
|
|
@@ -1910,7 +1901,7 @@ class Deserializer(object):
|
|
1910
1901
|
if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore
|
1911
1902
|
raise DeserializationError("Date must have only digits and -. Received: %s" % attr)
|
1912
1903
|
# This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception.
|
1913
|
-
return isodate.parse_date(attr, defaultmonth=
|
1904
|
+
return isodate.parse_date(attr, defaultmonth=0, defaultday=0)
|
1914
1905
|
|
1915
1906
|
@staticmethod
|
1916
1907
|
def deserialize_time(attr):
|
@@ -1945,7 +1936,7 @@ class Deserializer(object):
|
|
1945
1936
|
date_obj = date_obj.astimezone(tz=TZ_UTC)
|
1946
1937
|
except ValueError as err:
|
1947
1938
|
msg = "Cannot deserialize to rfc datetime object."
|
1948
|
-
|
1939
|
+
raise DeserializationError(msg) from err
|
1949
1940
|
else:
|
1950
1941
|
return date_obj
|
1951
1942
|
|
@@ -1982,7 +1973,7 @@ class Deserializer(object):
|
|
1982
1973
|
raise OverflowError("Hit max or min date")
|
1983
1974
|
except (ValueError, OverflowError, AttributeError) as err:
|
1984
1975
|
msg = "Cannot deserialize datetime object."
|
1985
|
-
|
1976
|
+
raise DeserializationError(msg) from err
|
1986
1977
|
else:
|
1987
1978
|
return date_obj
|
1988
1979
|
|
@@ -1998,9 +1989,10 @@ class Deserializer(object):
|
|
1998
1989
|
if isinstance(attr, ET.Element):
|
1999
1990
|
attr = int(attr.text) # type: ignore
|
2000
1991
|
try:
|
1992
|
+
attr = int(attr)
|
2001
1993
|
date_obj = datetime.datetime.fromtimestamp(attr, TZ_UTC)
|
2002
1994
|
except ValueError as err:
|
2003
1995
|
msg = "Cannot deserialize to unix datetime object."
|
2004
|
-
|
1996
|
+
raise DeserializationError(msg) from err
|
2005
1997
|
else:
|
2006
1998
|
return date_obj
|
@@ -10,6 +10,7 @@ from copy import deepcopy
|
|
10
10
|
from typing import Any, Awaitable
|
11
11
|
|
12
12
|
from azure.core import AsyncPipelineClient
|
13
|
+
from azure.core.pipeline import policies
|
13
14
|
from azure.core.rest import AsyncHttpResponse, HttpRequest
|
14
15
|
|
15
16
|
from .. import models as _models
|
@@ -54,7 +55,24 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
54
55
|
self, url: str, base_url: str = "", **kwargs: Any
|
55
56
|
) -> None:
|
56
57
|
self._config = AzureBlobStorageConfiguration(url=url, **kwargs)
|
57
|
-
|
58
|
+
_policies = kwargs.pop("policies", None)
|
59
|
+
if _policies is None:
|
60
|
+
_policies = [
|
61
|
+
policies.RequestIdPolicy(**kwargs),
|
62
|
+
self._config.headers_policy,
|
63
|
+
self._config.user_agent_policy,
|
64
|
+
self._config.proxy_policy,
|
65
|
+
policies.ContentDecodePolicy(**kwargs),
|
66
|
+
self._config.redirect_policy,
|
67
|
+
self._config.retry_policy,
|
68
|
+
self._config.authentication_policy,
|
69
|
+
self._config.custom_hook_policy,
|
70
|
+
self._config.logging_policy,
|
71
|
+
policies.DistributedTracingPolicy(**kwargs),
|
72
|
+
policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,
|
73
|
+
self._config.http_logging_policy,
|
74
|
+
]
|
75
|
+
self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=base_url, policies=_policies, **kwargs)
|
58
76
|
|
59
77
|
client_models = {k: v for k, v in _models.__dict__.items() if isinstance(v, type)}
|
60
78
|
self._serialize = Serializer(client_models)
|
@@ -67,7 +85,9 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
67
85
|
self.append_blob = AppendBlobOperations(self._client, self._config, self._serialize, self._deserialize)
|
68
86
|
self.block_blob = BlockBlobOperations(self._client, self._config, self._serialize, self._deserialize)
|
69
87
|
|
70
|
-
def _send_request(
|
88
|
+
def _send_request(
|
89
|
+
self, request: HttpRequest, *, stream: bool = False, **kwargs: Any
|
90
|
+
) -> Awaitable[AsyncHttpResponse]:
|
71
91
|
"""Runs the network request through the client's chained policies.
|
72
92
|
|
73
93
|
>>> from azure.core.rest import HttpRequest
|
@@ -87,7 +107,7 @@ class AzureBlobStorage: # pylint: disable=client-accepts-api-version-keyword
|
|
87
107
|
|
88
108
|
request_copy = deepcopy(request)
|
89
109
|
request_copy.url = self._client.format_url(request_copy.url)
|
90
|
-
return self._client.send_request(request_copy, **kwargs)
|
110
|
+
return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore
|
91
111
|
|
92
112
|
async def close(self) -> None:
|
93
113
|
await self._client.close()
|
@@ -6,21 +6,14 @@
|
|
6
6
|
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
7
7
|
# --------------------------------------------------------------------------
|
8
8
|
|
9
|
-
import
|
10
|
-
from typing import Any
|
9
|
+
from typing import Any, Literal
|
11
10
|
|
12
|
-
from azure.core.configuration import Configuration
|
13
11
|
from azure.core.pipeline import policies
|
14
12
|
|
15
|
-
if sys.version_info >= (3, 8):
|
16
|
-
from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
|
17
|
-
else:
|
18
|
-
from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports
|
19
|
-
|
20
13
|
VERSION = "unknown"
|
21
14
|
|
22
15
|
|
23
|
-
class AzureBlobStorageConfiguration
|
16
|
+
class AzureBlobStorageConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long
|
24
17
|
"""Configuration for AzureBlobStorage.
|
25
18
|
|
26
19
|
Note that all parameters used to create this instance are saved as instance
|
@@ -35,7 +28,6 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
35
28
|
"""
|
36
29
|
|
37
30
|
def __init__(self, url: str, **kwargs: Any) -> None:
|
38
|
-
super(AzureBlobStorageConfiguration, self).__init__(**kwargs)
|
39
31
|
version: Literal["2021-12-02"] = kwargs.pop("version", "2021-12-02")
|
40
32
|
|
41
33
|
if url is None:
|
@@ -44,6 +36,7 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
44
36
|
self.url = url
|
45
37
|
self.version = version
|
46
38
|
kwargs.setdefault("sdk_moniker", "azureblobstorage/{}".format(VERSION))
|
39
|
+
self.polling_interval = kwargs.get("polling_interval", 30)
|
47
40
|
self._configure(**kwargs)
|
48
41
|
|
49
42
|
def _configure(self, **kwargs: Any) -> None:
|
@@ -52,7 +45,7 @@ class AzureBlobStorageConfiguration(Configuration): # pylint: disable=too-many-
|
|
52
45
|
self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs)
|
53
46
|
self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs)
|
54
47
|
self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs)
|
55
|
-
self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs)
|
56
48
|
self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs)
|
57
49
|
self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs)
|
50
|
+
self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs)
|
58
51
|
self.authentication_policy = kwargs.get("authentication_policy")
|