azure-storage-blob 12.26.0b1__py3-none-any.whl → 12.27.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.
Files changed (64) hide show
  1. azure/storage/blob/__init__.py +3 -2
  2. azure/storage/blob/_blob_client.py +43 -38
  3. azure/storage/blob/_blob_client_helpers.py +4 -3
  4. azure/storage/blob/_blob_service_client.py +16 -13
  5. azure/storage/blob/_container_client.py +25 -22
  6. azure/storage/blob/_deserialize.py +1 -1
  7. azure/storage/blob/_download.py +7 -7
  8. azure/storage/blob/_encryption.py +177 -184
  9. azure/storage/blob/_generated/_azure_blob_storage.py +3 -2
  10. azure/storage/blob/_generated/_configuration.py +2 -2
  11. azure/storage/blob/_generated/_utils/__init__.py +6 -0
  12. azure/storage/blob/_generated/{_serialization.py → _utils/serialization.py} +4 -22
  13. azure/storage/blob/_generated/aio/_azure_blob_storage.py +3 -2
  14. azure/storage/blob/_generated/aio/_configuration.py +2 -2
  15. azure/storage/blob/_generated/aio/operations/_append_blob_operations.py +6 -10
  16. azure/storage/blob/_generated/aio/operations/_blob_operations.py +35 -39
  17. azure/storage/blob/_generated/aio/operations/_block_blob_operations.py +9 -13
  18. azure/storage/blob/_generated/aio/operations/_container_operations.py +20 -24
  19. azure/storage/blob/_generated/aio/operations/_page_blob_operations.py +13 -17
  20. azure/storage/blob/_generated/aio/operations/_service_operations.py +10 -14
  21. azure/storage/blob/_generated/models/_models_py3.py +30 -9
  22. azure/storage/blob/_generated/operations/_append_blob_operations.py +11 -15
  23. azure/storage/blob/_generated/operations/_blob_operations.py +60 -64
  24. azure/storage/blob/_generated/operations/_block_blob_operations.py +16 -20
  25. azure/storage/blob/_generated/operations/_container_operations.py +39 -43
  26. azure/storage/blob/_generated/operations/_page_blob_operations.py +23 -27
  27. azure/storage/blob/_generated/operations/_service_operations.py +19 -23
  28. azure/storage/blob/_lease.py +1 -0
  29. azure/storage/blob/_list_blobs_helper.py +1 -1
  30. azure/storage/blob/_quick_query_helper.py +3 -3
  31. azure/storage/blob/_serialize.py +1 -0
  32. azure/storage/blob/_shared/__init__.py +7 -7
  33. azure/storage/blob/_shared/authentication.py +49 -32
  34. azure/storage/blob/_shared/avro/avro_io.py +44 -42
  35. azure/storage/blob/_shared/avro/avro_io_async.py +42 -41
  36. azure/storage/blob/_shared/avro/datafile.py +24 -21
  37. azure/storage/blob/_shared/avro/datafile_async.py +15 -15
  38. azure/storage/blob/_shared/avro/schema.py +196 -217
  39. azure/storage/blob/_shared/base_client.py +81 -59
  40. azure/storage/blob/_shared/base_client_async.py +58 -51
  41. azure/storage/blob/_shared/constants.py +1 -1
  42. azure/storage/blob/_shared/models.py +94 -92
  43. azure/storage/blob/_shared/parser.py +3 -3
  44. azure/storage/blob/_shared/policies.py +186 -147
  45. azure/storage/blob/_shared/policies_async.py +53 -65
  46. azure/storage/blob/_shared/request_handlers.py +50 -45
  47. azure/storage/blob/_shared/response_handlers.py +54 -45
  48. azure/storage/blob/_shared/shared_access_signature.py +65 -73
  49. azure/storage/blob/_shared/uploads.py +56 -49
  50. azure/storage/blob/_shared/uploads_async.py +70 -58
  51. azure/storage/blob/_version.py +1 -1
  52. azure/storage/blob/aio/__init__.py +3 -2
  53. azure/storage/blob/aio/_blob_client_async.py +53 -40
  54. azure/storage/blob/aio/_blob_service_client_async.py +13 -11
  55. azure/storage/blob/aio/_container_client_async.py +28 -25
  56. azure/storage/blob/aio/_download_async.py +7 -7
  57. azure/storage/blob/aio/_lease_async.py +1 -0
  58. azure/storage/blob/aio/_quick_query_helper_async.py +3 -3
  59. {azure_storage_blob-12.26.0b1.dist-info → azure_storage_blob-12.27.0b1.dist-info}/METADATA +3 -4
  60. azure_storage_blob-12.27.0b1.dist-info/RECORD +86 -0
  61. azure_storage_blob-12.26.0b1.dist-info/RECORD +0 -85
  62. {azure_storage_blob-12.26.0b1.dist-info → azure_storage_blob-12.27.0b1.dist-info}/LICENSE +0 -0
  63. {azure_storage_blob-12.26.0b1.dist-info → azure_storage_blob-12.27.0b1.dist-info}/WHEEL +0 -0
  64. {azure_storage_blob-12.26.0b1.dist-info → azure_storage_blob-12.27.0b1.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ from itertools import islice
12
12
  from math import ceil
13
13
  from typing import AsyncGenerator, Union
14
14
 
15
- from .import encode_base64, url_quote
15
+ from . import encode_base64, url_quote
16
16
  from .request_handlers import get_length
17
17
  from .response_handlers import return_response_headers
18
18
  from .uploads import SubStream, IterStreamer # pylint: disable=unused-import
@@ -59,19 +59,20 @@ async def _parallel_uploads(uploader, pending, running):
59
59
 
60
60
 
61
61
  async def upload_data_chunks(
62
- service=None,
63
- uploader_class=None,
64
- total_size=None,
65
- chunk_size=None,
66
- max_concurrency=None,
67
- stream=None,
68
- progress_hook=None,
69
- **kwargs):
62
+ service=None,
63
+ uploader_class=None,
64
+ total_size=None,
65
+ chunk_size=None,
66
+ max_concurrency=None,
67
+ stream=None,
68
+ progress_hook=None,
69
+ **kwargs,
70
+ ):
70
71
 
71
72
  parallel = max_concurrency > 1
72
- if parallel and 'modified_access_conditions' in kwargs:
73
+ if parallel and "modified_access_conditions" in kwargs:
73
74
  # Access conditions do not work with parallelism
74
- kwargs['modified_access_conditions'] = None
75
+ kwargs["modified_access_conditions"] = None
75
76
 
76
77
  uploader = uploader_class(
77
78
  service=service,
@@ -80,7 +81,8 @@ async def upload_data_chunks(
80
81
  stream=stream,
81
82
  parallel=parallel,
82
83
  progress_hook=progress_hook,
83
- **kwargs)
84
+ **kwargs,
85
+ )
84
86
 
85
87
  if parallel:
86
88
  upload_tasks = uploader.get_chunk_streams()
@@ -104,18 +106,19 @@ async def upload_data_chunks(
104
106
 
105
107
 
106
108
  async def upload_substream_blocks(
107
- service=None,
108
- uploader_class=None,
109
- total_size=None,
110
- chunk_size=None,
111
- max_concurrency=None,
112
- stream=None,
113
- progress_hook=None,
114
- **kwargs):
109
+ service=None,
110
+ uploader_class=None,
111
+ total_size=None,
112
+ chunk_size=None,
113
+ max_concurrency=None,
114
+ stream=None,
115
+ progress_hook=None,
116
+ **kwargs,
117
+ ):
115
118
  parallel = max_concurrency > 1
116
- if parallel and 'modified_access_conditions' in kwargs:
119
+ if parallel and "modified_access_conditions" in kwargs:
117
120
  # Access conditions do not work with parallelism
118
- kwargs['modified_access_conditions'] = None
121
+ kwargs["modified_access_conditions"] = None
119
122
  uploader = uploader_class(
120
123
  service=service,
121
124
  total_size=total_size,
@@ -123,13 +126,13 @@ async def upload_substream_blocks(
123
126
  stream=stream,
124
127
  parallel=parallel,
125
128
  progress_hook=progress_hook,
126
- **kwargs)
129
+ **kwargs,
130
+ )
127
131
 
128
132
  if parallel:
129
133
  upload_tasks = uploader.get_substream_blocks()
130
134
  running_futures = [
131
- asyncio.ensure_future(uploader.process_substream_block(u))
132
- for u in islice(upload_tasks, 0, max_concurrency)
135
+ asyncio.ensure_future(uploader.process_substream_block(u)) for u in islice(upload_tasks, 0, max_concurrency)
133
136
  ]
134
137
  range_ids = await _parallel_uploads(uploader.process_substream_block, upload_tasks, running_futures)
135
138
  else:
@@ -144,15 +147,17 @@ async def upload_substream_blocks(
144
147
  class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
145
148
 
146
149
  def __init__(
147
- self, service,
148
- total_size,
149
- chunk_size,
150
- stream,
151
- parallel,
152
- encryptor=None,
153
- padder=None,
154
- progress_hook=None,
155
- **kwargs):
150
+ self,
151
+ service,
152
+ total_size,
153
+ chunk_size,
154
+ stream,
155
+ parallel,
156
+ encryptor=None,
157
+ padder=None,
158
+ progress_hook=None,
159
+ **kwargs,
160
+ ):
156
161
  self.service = service
157
162
  self.total_size = total_size
158
163
  self.chunk_size = chunk_size
@@ -178,7 +183,7 @@ class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
178
183
  async def get_chunk_streams(self):
179
184
  index = 0
180
185
  while True:
181
- data = b''
186
+ data = b""
182
187
  read_size = self.chunk_size
183
188
 
184
189
  # Buffer until we either reach the end of the stream or get a whole chunk.
@@ -189,12 +194,12 @@ class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
189
194
  if inspect.isawaitable(temp):
190
195
  temp = await temp
191
196
  if not isinstance(temp, bytes):
192
- raise TypeError('Blob data should be of type bytes.')
197
+ raise TypeError("Blob data should be of type bytes.")
193
198
  data += temp or b""
194
199
 
195
200
  # We have read an empty string and so are at the end
196
201
  # of the buffer or we have read a full chunk.
197
- if temp == b'' or len(data) == self.chunk_size:
202
+ if temp == b"" or len(data) == self.chunk_size:
198
203
  break
199
204
 
200
205
  if len(data) == self.chunk_size:
@@ -273,13 +278,13 @@ class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
273
278
  class BlockBlobChunkUploader(_ChunkUploader):
274
279
 
275
280
  def __init__(self, *args, **kwargs):
276
- kwargs.pop('modified_access_conditions', None)
281
+ kwargs.pop("modified_access_conditions", None)
277
282
  super(BlockBlobChunkUploader, self).__init__(*args, **kwargs)
278
283
  self.current_length = None
279
284
 
280
285
  async def _upload_chunk(self, chunk_offset, chunk_data):
281
286
  # TODO: This is incorrect, but works with recording.
282
- index = f'{chunk_offset:032d}'
287
+ index = f"{chunk_offset:032d}"
283
288
  block_id = encode_base64(url_quote(encode_base64(index)))
284
289
  await self.service.stage_block(
285
290
  block_id,
@@ -287,19 +292,21 @@ class BlockBlobChunkUploader(_ChunkUploader):
287
292
  body=chunk_data,
288
293
  data_stream_total=self.total_size,
289
294
  upload_stream_current=self.progress_total,
290
- **self.request_options)
295
+ **self.request_options,
296
+ )
291
297
  return index, block_id
292
298
 
293
299
  async def _upload_substream_block(self, index, block_stream):
294
300
  try:
295
- block_id = f'BlockId{(index//self.chunk_size):05}'
301
+ block_id = f"BlockId{(index//self.chunk_size):05}"
296
302
  await self.service.stage_block(
297
303
  block_id,
298
304
  len(block_stream),
299
305
  block_stream,
300
306
  data_stream_total=self.total_size,
301
307
  upload_stream_current=self.progress_total,
302
- **self.request_options)
308
+ **self.request_options,
309
+ )
303
310
  finally:
304
311
  block_stream.close()
305
312
  return block_id
@@ -311,7 +318,7 @@ class PageBlobChunkUploader(_ChunkUploader):
311
318
  # read until non-zero byte is encountered
312
319
  # if reached the end without returning, then chunk_data is all 0's
313
320
  for each_byte in chunk_data:
314
- if each_byte not in [0, b'\x00']:
321
+ if each_byte not in [0, b"\x00"]:
315
322
  return False
316
323
  return True
317
324
 
@@ -319,7 +326,7 @@ class PageBlobChunkUploader(_ChunkUploader):
319
326
  # avoid uploading the empty pages
320
327
  if not self._is_chunk_empty(chunk_data):
321
328
  chunk_end = chunk_offset + len(chunk_data) - 1
322
- content_range = f'bytes={chunk_offset}-{chunk_end}'
329
+ content_range = f"bytes={chunk_offset}-{chunk_end}"
323
330
  computed_md5 = None
324
331
  self.response_headers = await self.service.upload_pages(
325
332
  body=chunk_data,
@@ -329,10 +336,11 @@ class PageBlobChunkUploader(_ChunkUploader):
329
336
  cls=return_response_headers,
330
337
  data_stream_total=self.total_size,
331
338
  upload_stream_current=self.progress_total,
332
- **self.request_options)
339
+ **self.request_options,
340
+ )
333
341
 
334
- if not self.parallel and self.request_options.get('modified_access_conditions'):
335
- self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
342
+ if not self.parallel and self.request_options.get("modified_access_conditions"):
343
+ self.request_options["modified_access_conditions"].if_match = self.response_headers["etag"]
336
344
 
337
345
  async def _upload_substream_block(self, index, block_stream):
338
346
  pass
@@ -352,18 +360,21 @@ class AppendBlobChunkUploader(_ChunkUploader):
352
360
  cls=return_response_headers,
353
361
  data_stream_total=self.total_size,
354
362
  upload_stream_current=self.progress_total,
355
- **self.request_options)
356
- self.current_length = int(self.response_headers['blob_append_offset'])
363
+ **self.request_options,
364
+ )
365
+ self.current_length = int(self.response_headers["blob_append_offset"])
357
366
  else:
358
- self.request_options['append_position_access_conditions'].append_position = \
367
+ self.request_options["append_position_access_conditions"].append_position = (
359
368
  self.current_length + chunk_offset
369
+ )
360
370
  self.response_headers = await self.service.append_block(
361
371
  body=chunk_data,
362
372
  content_length=len(chunk_data),
363
373
  cls=return_response_headers,
364
374
  data_stream_total=self.total_size,
365
375
  upload_stream_current=self.progress_total,
366
- **self.request_options)
376
+ **self.request_options,
377
+ )
367
378
 
368
379
  async def _upload_substream_block(self, index, block_stream):
369
380
  pass
@@ -379,11 +390,11 @@ class DataLakeFileChunkUploader(_ChunkUploader):
379
390
  cls=return_response_headers,
380
391
  data_stream_total=self.total_size,
381
392
  upload_stream_current=self.progress_total,
382
- **self.request_options
393
+ **self.request_options,
383
394
  )
384
395
 
385
- if not self.parallel and self.request_options.get('modified_access_conditions'):
386
- self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
396
+ if not self.parallel and self.request_options.get("modified_access_conditions"):
397
+ self.request_options["modified_access_conditions"].if_match = self.response_headers["etag"]
387
398
 
388
399
  async def _upload_substream_block(self, index, block_stream):
389
400
  try:
@@ -394,7 +405,7 @@ class DataLakeFileChunkUploader(_ChunkUploader):
394
405
  cls=return_response_headers,
395
406
  data_stream_total=self.total_size,
396
407
  upload_stream_current=self.progress_total,
397
- **self.request_options
408
+ **self.request_options,
398
409
  )
399
410
  finally:
400
411
  block_stream.close()
@@ -411,9 +422,9 @@ class FileChunkUploader(_ChunkUploader):
411
422
  length,
412
423
  data_stream_total=self.total_size,
413
424
  upload_stream_current=self.progress_total,
414
- **self.request_options
425
+ **self.request_options,
415
426
  )
416
- range_id = f'bytes={chunk_offset}-{chunk_end}'
427
+ range_id = f"bytes={chunk_offset}-{chunk_end}"
417
428
  return range_id, response
418
429
 
419
430
  # TODO: Implement this method.
@@ -421,10 +432,11 @@ class FileChunkUploader(_ChunkUploader):
421
432
  pass
422
433
 
423
434
 
424
- class AsyncIterStreamer():
435
+ class AsyncIterStreamer:
425
436
  """
426
437
  File-like streaming object for AsyncGenerators.
427
438
  """
439
+
428
440
  def __init__(self, generator: AsyncGenerator[Union[bytes, str], None], encoding: str = "UTF-8"):
429
441
  self.iterator = generator.__aiter__()
430
442
  self.leftover = b""
@@ -4,4 +4,4 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
 
7
- VERSION = "12.26.0b1"
7
+ VERSION = "12.27.0b1"
@@ -73,7 +73,7 @@ async def upload_blob_to_url(
73
73
  entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
74
74
  :keyword str encoding:
75
75
  Encoding to use if text is supplied as input. Defaults to UTF-8.
76
- :returns: Blob-updated property dict (Etag and last modified)
76
+ :return: Blob-updated property dict (Etag and last modified)
77
77
  :rtype: dict[str, Any]
78
78
  """
79
79
  async with BlobClient.from_blob_url(blob_url, credential=credential) as client:
@@ -102,7 +102,7 @@ async def download_blob_from_url(
102
102
  :param output:
103
103
  Where the data should be downloaded to. This could be either a file path to write to,
104
104
  or an open IO handle to write to.
105
- :type output: str or writable stream
105
+ :type output: str or IO
106
106
  :param credential:
107
107
  The credentials with which to authenticate. This is optional if the
108
108
  blob URL already has a SAS token or the blob is public. The value can be a SAS token string,
@@ -139,6 +139,7 @@ async def download_blob_from_url(
139
139
  blob. Also note that if enabled, the memory-efficient upload algorithm
140
140
  will not be used, because computing the MD5 hash requires buffering
141
141
  entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
142
+ :return: None
142
143
  :rtype: None
143
144
  """
144
145
  overwrite = kwargs.pop('overwrite', False)