|
16 | 16 | TYPE_CHECKING,
|
17 | 17 | )
|
18 | 18 | import logging
|
| 19 | +from uuid import uuid4 |
19 | 20 |
|
20 | 21 |
|
21 | 22 |
|
|
29 | 30 | from azure.core.configuration import Configuration
|
30 | 31 | from azure.core.exceptions import HttpResponseError
|
31 | 32 | from azure.core.pipeline import Pipeline
|
32 |
| -from azure.core.pipeline.transport import RequestsTransport, HttpTransport |
| 33 | +from azure.core.pipeline.transport import ( |
| 34 | + RequestsTransport, |
| 35 | + HttpTransport, |
| 36 | + HttpRequest, |
| 37 | +) |
33 | 38 | from azure.core.pipeline.policies import (
|
34 | 39 | RedirectPolicy,
|
35 | 40 | ContentDecodePolicy,
|
|
42 | 47 |
|
43 | 48 | from ._shared_access_signature import QueryStringConstants
|
44 | 49 | from ._constants import STORAGE_OAUTH_SCOPE, SERVICE_HOST_BASE, CONNECTION_TIMEOUT, READ_TIMEOUT
|
45 |
| -from ._models import LocationMode |
| 50 | +from ._models import LocationMode, BatchTransactionResult |
46 | 51 | from ._authentication import SharedKeyCredentialPolicy
|
47 | 52 | from ._policies import (
|
48 | 53 | StorageHeadersPolicy,
|
|
54 | 59 | TablesRetryPolicy,
|
55 | 60 | )
|
56 | 61 | from ._error import _process_table_error
|
57 |
| -from ._models import PartialBatchErrorException |
| 62 | +from ._models import BatchErrorException |
58 | 63 | from ._sdk_moniker import SDK_MONIKER
|
59 | 64 |
|
60 | 65 |
|
@@ -251,54 +256,55 @@ def _create_pipeline(self, credential, **kwargs):
|
251 | 256 | return config, Pipeline(config.transport, policies=policies)
|
252 | 257 |
|
253 | 258 | def _batch_send(
|
254 |
| - self, *reqs, # type: HttpRequest |
| 259 | + self, entities, # type: List[TableEntity] |
| 260 | + *reqs, # type: List[HttpRequest] |
255 | 261 | **kwargs
|
256 | 262 | ):
|
| 263 | + # (...) -> List[HttpResponse] |
257 | 264 | """Given a series of request, do a Storage batch call.
|
258 | 265 | """
|
259 | 266 | # Pop it here, so requests doesn't feel bad about additional kwarg
|
260 | 267 | raise_on_any_failure = kwargs.pop("raise_on_any_failure", True)
|
| 268 | + policies = [StorageHeadersPolicy()] |
| 269 | + |
| 270 | + changeset = HttpRequest('POST', None) |
| 271 | + changeset.set_multipart_mixed( |
| 272 | + *reqs, |
| 273 | + policies=policies, |
| 274 | + boundary="changeset_{}".format(uuid4()) |
| 275 | + ) |
261 | 276 | request = self._client._client.post( # pylint: disable=protected-access
|
262 |
| - url='{}://{}/?comp=batch{}{}'.format( |
263 |
| - self.scheme, |
264 |
| - self._primary_hostname, |
265 |
| - kwargs.pop('sas', None), |
266 |
| - kwargs.pop('timeout', None) |
267 |
| - ), |
| 277 | + url='https://{}/$batch'.format(self._primary_hostname), |
268 | 278 | headers={
|
269 |
| - 'x-ms-version': self.api_version |
| 279 | + 'x-ms-version': self.api_version, |
| 280 | + 'DataServiceVersion': '3.0', |
| 281 | + 'MaxDataServiceVersion': '3.0;NetFx', |
270 | 282 | }
|
271 | 283 | )
|
272 |
| - |
273 |
| - policies = [StorageHeadersPolicy()] |
274 |
| - if self._credential_policy: |
275 |
| - policies.append(self._credential_policy) |
276 |
| - |
277 | 284 | request.set_multipart_mixed(
|
278 |
| - *reqs, |
| 285 | + changeset, |
279 | 286 | policies=policies,
|
280 |
| - enforce_https=False |
| 287 | + enforce_https=False, |
| 288 | + boundary="batch_{}".format(uuid4()) |
281 | 289 | )
|
282 | 290 |
|
283 | 291 | pipeline_response = self._pipeline.run(
|
284 | 292 | request, **kwargs
|
285 | 293 | )
|
286 | 294 | response = pipeline_response.http_response
|
287 |
| - |
288 | 295 | try:
|
289 | 296 | if response.status_code not in [202]:
|
290 | 297 | raise HttpResponseError(response=response)
|
291 | 298 | parts = response.parts()
|
| 299 | + transaction_result = BatchTransactionResult(reqs, parts, entities) |
292 | 300 | if raise_on_any_failure:
|
293 |
| - parts = list(response.parts()) |
294 | 301 | if any(p for p in parts if not 200 <= p.status_code < 300):
|
295 |
| - error = PartialBatchErrorException( |
296 |
| - message="There is a partial failure in the batch operation.", |
| 302 | + error = BatchErrorException( |
| 303 | + message="There is a failure in the batch operation.", |
297 | 304 | response=response, parts=parts
|
298 | 305 | )
|
299 | 306 | raise error
|
300 |
| - return iter(parts) |
301 |
| - return parts |
| 307 | + return transaction_result |
302 | 308 | except HttpResponseError as error:
|
303 | 309 | _process_table_error(error)
|
304 | 310 |
|
|
0 commit comments