google-cloud-storage 3.3.0__tar.gz → 3.3.1__tar.gz
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.
- {google_cloud_storage-3.3.0/google_cloud_storage.egg-info → google_cloud_storage-3.3.1}/PKG-INFO +1 -1
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/_upload.py +41 -3
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/requests/upload.py +9 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/blob.py +49 -11
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/bucket.py +23 -3
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/version.py +1 -1
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1/google_cloud_storage.egg-info}/PKG-INFO +1 -1
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/SOURCES.txt +1 -0
- google_cloud_storage-3.3.1/tests/data/random_9_MiB_file +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/requests/test_upload.py +65 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/test__upload.py +28 -3
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/conftest.py +1 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test__signing.py +13 -39
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_blob.py +56 -24
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_blob.py +25 -1
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/LICENSE +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/MANIFEST.in +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/README.rst +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_http.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/_download.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/_helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/common.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/py.typed +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/requests/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/requests/_request_helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/requests/download.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_opentelemetry_tracing.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_signing.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/acl.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/batch.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/client.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/constants.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/exceptions.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/fileio.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/hmac_key.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/iam.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/ip_filter.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/notification.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/retry.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/transfer_manager.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/gapic_metadata.json +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/gapic_version.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/py.typed +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/async_client.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/client.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/pagers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/transports/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/transports/base.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/transports/grpc.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/services/storage/transports/grpc_asyncio.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/types/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage_v2/types/storage.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/dependency_links.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/not-zip-safe +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/requires.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/top_level.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/setup.cfg +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/setup.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/conformance/README.md +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/conformance/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/conformance/conftest.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/conformance/retry_strategy_test_data.json +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/conformance/test_conformance.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/data/CloudPlatform_128px_Retina.png +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/data/five-point-one-mb-file.zip +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/data/simple.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/perf/README.md +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/perf/_perf_utils.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/perf/benchmarking.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/perf/profile_w1r3.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/brotli.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/brotli.txt.br +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/favicon.ico +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/file.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/gzipped.txt +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/gzipped.txt.gz +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/image1.jpg +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/data/image2.jpg +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/credentials.json.enc +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/requests/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/requests/conftest.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/requests/test_download.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/requests/test_upload.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/system/utils.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/requests/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/requests/test__helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/requests/test_download.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/test__download.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/test__helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/_helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_bucket.py +1 -1
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_client.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_fileio.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_hmac_key_metadata.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_kms_integration.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_notification.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/system/test_transfer_manager.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/gapic/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/gapic/storage_v2/__init__.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/gapic/storage_v2/test_storage.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test__helpers.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test__http.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test__opentelemetry_tracing.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test__signing.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_acl.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_batch.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_bucket.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_client.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_exceptions.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_fileio.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_hmac_key.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_ip_filter.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_notification.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_retry.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/test_transfer_manager.py +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/url_signer_v4_test_account.json +0 -0
- {google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/unit/url_signer_v4_test_data.json +0 -0
{google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google/cloud/storage/_media/_upload.py
RENAMED
|
@@ -411,7 +411,12 @@ class ResumableUpload(UploadBase):
|
|
|
411
411
|
"""
|
|
412
412
|
|
|
413
413
|
def __init__(
|
|
414
|
-
self,
|
|
414
|
+
self,
|
|
415
|
+
upload_url,
|
|
416
|
+
chunk_size,
|
|
417
|
+
checksum="auto",
|
|
418
|
+
headers=None,
|
|
419
|
+
retry=DEFAULT_RETRY,
|
|
415
420
|
):
|
|
416
421
|
super(ResumableUpload, self).__init__(upload_url, headers=headers, retry=retry)
|
|
417
422
|
if chunk_size % UPLOAD_CHUNK_SIZE != 0:
|
|
@@ -472,7 +477,12 @@ class ResumableUpload(UploadBase):
|
|
|
472
477
|
return self._total_bytes
|
|
473
478
|
|
|
474
479
|
def _prepare_initiate_request(
|
|
475
|
-
self,
|
|
480
|
+
self,
|
|
481
|
+
stream,
|
|
482
|
+
metadata,
|
|
483
|
+
content_type,
|
|
484
|
+
total_bytes=None,
|
|
485
|
+
stream_final=True,
|
|
476
486
|
):
|
|
477
487
|
"""Prepare the contents of HTTP request to initiate upload.
|
|
478
488
|
|
|
@@ -955,7 +965,12 @@ class XMLMPUContainer(UploadBase):
|
|
|
955
965
|
"""
|
|
956
966
|
|
|
957
967
|
def __init__(
|
|
958
|
-
self,
|
|
968
|
+
self,
|
|
969
|
+
upload_url,
|
|
970
|
+
filename,
|
|
971
|
+
headers=None,
|
|
972
|
+
upload_id=None,
|
|
973
|
+
retry=DEFAULT_RETRY,
|
|
959
974
|
):
|
|
960
975
|
super().__init__(upload_url, headers=headers, retry=retry)
|
|
961
976
|
self._filename = filename
|
|
@@ -1372,6 +1387,29 @@ class XMLMPUPart(UploadBase):
|
|
|
1372
1387
|
|
|
1373
1388
|
.. _sans-I/O: https://sans-io.readthedocs.io/
|
|
1374
1389
|
"""
|
|
1390
|
+
# Data corruption errors shouldn't be considered as invalid responses,
|
|
1391
|
+
# So we handle them earlier than call to `_helpers.require_status_code`.
|
|
1392
|
+
# If the response is 400, we check for data corruption errors.
|
|
1393
|
+
if response.status_code == 400:
|
|
1394
|
+
root = ElementTree.fromstring(response.text)
|
|
1395
|
+
error_code = root.find("Code").text
|
|
1396
|
+
error_message = root.find("Message").text
|
|
1397
|
+
error_details = root.find("Details").text
|
|
1398
|
+
if error_code in ["InvalidDigest", "BadDigest", "CrcMismatch"]:
|
|
1399
|
+
raise DataCorruption(
|
|
1400
|
+
response,
|
|
1401
|
+
(
|
|
1402
|
+
"Checksum mismatch: checksum calculated by client and"
|
|
1403
|
+
" server did not match. Error code: {error_code},"
|
|
1404
|
+
" Error message: {error_message},"
|
|
1405
|
+
" Error details: {error_details}"
|
|
1406
|
+
).format(
|
|
1407
|
+
error_code=error_code,
|
|
1408
|
+
error_message=error_message,
|
|
1409
|
+
error_details=error_details,
|
|
1410
|
+
),
|
|
1411
|
+
)
|
|
1412
|
+
|
|
1375
1413
|
_helpers.require_status_code(
|
|
1376
1414
|
response,
|
|
1377
1415
|
(http.client.OK,),
|
|
@@ -21,6 +21,7 @@ uploads that contain both metadata and a small file as payload.
|
|
|
21
21
|
|
|
22
22
|
from google.cloud.storage._media import _upload
|
|
23
23
|
from google.cloud.storage._media.requests import _request_helpers
|
|
24
|
+
from google.cloud.storage._media import _helpers
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class SimpleUpload(_request_helpers.RequestsMixin, _upload.SimpleUpload):
|
|
@@ -757,6 +758,14 @@ class XMLMPUPart(_request_helpers.RequestsMixin, _upload.XMLMPUPart):
|
|
|
757
758
|
~requests.Response: The HTTP response returned by ``transport``.
|
|
758
759
|
"""
|
|
759
760
|
method, url, payload, headers = self._prepare_upload_request()
|
|
761
|
+
if self._checksum_object is not None:
|
|
762
|
+
checksum_digest_in_base64 = _helpers.prepare_checksum_digest(
|
|
763
|
+
self._checksum_object.digest()
|
|
764
|
+
)
|
|
765
|
+
if self._checksum_type == "crc32c":
|
|
766
|
+
headers["X-Goog-Hash"] = f"crc32c={checksum_digest_in_base64}"
|
|
767
|
+
elif self._checksum_type == "md5":
|
|
768
|
+
headers["X-Goog-Hash"] = f"md5={checksum_digest_in_base64}"
|
|
760
769
|
|
|
761
770
|
# Wrap the request business logic in a function to be retried.
|
|
762
771
|
def retriable_request():
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
# pylint: disable=too-many-lines
|
|
16
16
|
|
|
17
|
-
"""Create / interact with Google Cloud Storage blobs.
|
|
18
|
-
"""
|
|
17
|
+
"""Create / interact with Google Cloud Storage blobs."""
|
|
19
18
|
|
|
20
19
|
import base64
|
|
21
20
|
import copy
|
|
@@ -142,8 +141,8 @@ _GS_URL_REGEX_PATTERN = re.compile(
|
|
|
142
141
|
r"(?P<scheme>gs)://(?P<bucket_name>[a-z0-9_.-]+)/(?P<object_name>.+)"
|
|
143
142
|
)
|
|
144
143
|
|
|
145
|
-
_DEFAULT_CHUNKSIZE = 104857600 # 1024 * 1024 B * 100 = 100
|
|
146
|
-
_MAX_MULTIPART_SIZE = 8388608 # 8
|
|
144
|
+
_DEFAULT_CHUNKSIZE = 104857600 # 1024 * 1024 B * 100 = 100 MiB
|
|
145
|
+
_MAX_MULTIPART_SIZE = 8388608 # 8 MiB
|
|
147
146
|
|
|
148
147
|
_logger = logging.getLogger(__name__)
|
|
149
148
|
|
|
@@ -181,6 +180,14 @@ class Blob(_PropertyMixin):
|
|
|
181
180
|
:type generation: long
|
|
182
181
|
:param generation:
|
|
183
182
|
(Optional) If present, selects a specific revision of this object.
|
|
183
|
+
|
|
184
|
+
:type crc32c_checksum: str
|
|
185
|
+
:param crc32c_checksum:
|
|
186
|
+
(Optional) If set, the CRC32C checksum of the blob's content.
|
|
187
|
+
CRC32c checksum, as described in RFC 4960, Appendix B; encoded using
|
|
188
|
+
base64 in big-endian byte order. See
|
|
189
|
+
Apenndix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B
|
|
190
|
+
base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4
|
|
184
191
|
"""
|
|
185
192
|
|
|
186
193
|
_chunk_size = None # Default value for each instance.
|
|
@@ -214,6 +221,7 @@ class Blob(_PropertyMixin):
|
|
|
214
221
|
encryption_key=None,
|
|
215
222
|
kms_key_name=None,
|
|
216
223
|
generation=None,
|
|
224
|
+
crc32c_checksum=None,
|
|
217
225
|
):
|
|
218
226
|
"""
|
|
219
227
|
property :attr:`name`
|
|
@@ -237,6 +245,9 @@ class Blob(_PropertyMixin):
|
|
|
237
245
|
if generation is not None:
|
|
238
246
|
self._properties["generation"] = generation
|
|
239
247
|
|
|
248
|
+
if crc32c_checksum is not None:
|
|
249
|
+
self._properties["crc32c"] = crc32c_checksum
|
|
250
|
+
|
|
240
251
|
@property
|
|
241
252
|
def bucket(self):
|
|
242
253
|
"""Bucket which contains the object.
|
|
@@ -1643,7 +1654,9 @@ class Blob(_PropertyMixin):
|
|
|
1643
1654
|
:raises: :class:`google.cloud.exceptions.NotFound`
|
|
1644
1655
|
"""
|
|
1645
1656
|
warnings.warn(
|
|
1646
|
-
_DOWNLOAD_AS_STRING_DEPRECATED,
|
|
1657
|
+
_DOWNLOAD_AS_STRING_DEPRECATED,
|
|
1658
|
+
PendingDeprecationWarning,
|
|
1659
|
+
stacklevel=2,
|
|
1647
1660
|
)
|
|
1648
1661
|
with create_trace_span(name="Storage.Blob.downloadAsString"):
|
|
1649
1662
|
return self.download_as_bytes(
|
|
@@ -1999,12 +2012,18 @@ class Blob(_PropertyMixin):
|
|
|
1999
2012
|
transport = self._get_transport(client)
|
|
2000
2013
|
if "metadata" in self._properties and "metadata" not in self._changes:
|
|
2001
2014
|
self._changes.add("metadata")
|
|
2015
|
+
|
|
2002
2016
|
info = self._get_upload_arguments(client, content_type, command=command)
|
|
2003
2017
|
headers, object_metadata, content_type = info
|
|
2004
2018
|
|
|
2019
|
+
if "crc32c" in self._properties:
|
|
2020
|
+
object_metadata["crc32c"] = self._properties["crc32c"]
|
|
2021
|
+
|
|
2005
2022
|
hostname = _get_host_name(client._connection)
|
|
2006
2023
|
base_url = _MULTIPART_URL_TEMPLATE.format(
|
|
2007
|
-
hostname=hostname,
|
|
2024
|
+
hostname=hostname,
|
|
2025
|
+
bucket_path=self.bucket.path,
|
|
2026
|
+
api_version=_API_VERSION,
|
|
2008
2027
|
)
|
|
2009
2028
|
name_value_pairs = []
|
|
2010
2029
|
|
|
@@ -2195,9 +2214,14 @@ class Blob(_PropertyMixin):
|
|
|
2195
2214
|
if extra_headers is not None:
|
|
2196
2215
|
headers.update(extra_headers)
|
|
2197
2216
|
|
|
2217
|
+
if "crc32c" in self._properties:
|
|
2218
|
+
object_metadata["crc32c"] = self._properties["crc32c"]
|
|
2219
|
+
|
|
2198
2220
|
hostname = _get_host_name(client._connection)
|
|
2199
2221
|
base_url = _RESUMABLE_URL_TEMPLATE.format(
|
|
2200
|
-
hostname=hostname,
|
|
2222
|
+
hostname=hostname,
|
|
2223
|
+
bucket_path=self.bucket.path,
|
|
2224
|
+
api_version=_API_VERSION,
|
|
2201
2225
|
)
|
|
2202
2226
|
name_value_pairs = []
|
|
2203
2227
|
|
|
@@ -2234,7 +2258,11 @@ class Blob(_PropertyMixin):
|
|
|
2234
2258
|
|
|
2235
2259
|
upload_url = _add_query_parameters(base_url, name_value_pairs)
|
|
2236
2260
|
upload = ResumableUpload(
|
|
2237
|
-
upload_url,
|
|
2261
|
+
upload_url,
|
|
2262
|
+
chunk_size,
|
|
2263
|
+
headers=headers,
|
|
2264
|
+
checksum=checksum,
|
|
2265
|
+
retry=retry,
|
|
2238
2266
|
)
|
|
2239
2267
|
|
|
2240
2268
|
upload.initiate(
|
|
@@ -3426,7 +3454,11 @@ class Blob(_PropertyMixin):
|
|
|
3426
3454
|
return Policy.from_api_repr(info)
|
|
3427
3455
|
|
|
3428
3456
|
def test_iam_permissions(
|
|
3429
|
-
self,
|
|
3457
|
+
self,
|
|
3458
|
+
permissions,
|
|
3459
|
+
client=None,
|
|
3460
|
+
timeout=_DEFAULT_TIMEOUT,
|
|
3461
|
+
retry=DEFAULT_RETRY,
|
|
3430
3462
|
):
|
|
3431
3463
|
"""API call: test permissions
|
|
3432
3464
|
|
|
@@ -3693,7 +3725,10 @@ class Blob(_PropertyMixin):
|
|
|
3693
3725
|
|
|
3694
3726
|
source_objects = []
|
|
3695
3727
|
for source, source_generation in zip(sources, if_source_generation_match):
|
|
3696
|
-
source_object = {
|
|
3728
|
+
source_object = {
|
|
3729
|
+
"name": source.name,
|
|
3730
|
+
"generation": source.generation,
|
|
3731
|
+
}
|
|
3697
3732
|
|
|
3698
3733
|
preconditions = {}
|
|
3699
3734
|
if source_generation is not None:
|
|
@@ -4154,7 +4189,10 @@ class Blob(_PropertyMixin):
|
|
|
4154
4189
|
"encoding, errors and newline arguments are for text mode only"
|
|
4155
4190
|
)
|
|
4156
4191
|
return BlobWriter(
|
|
4157
|
-
self,
|
|
4192
|
+
self,
|
|
4193
|
+
chunk_size=chunk_size,
|
|
4194
|
+
ignore_flush=ignore_flush,
|
|
4195
|
+
**kwargs,
|
|
4158
4196
|
)
|
|
4159
4197
|
elif mode in ("r", "rt"):
|
|
4160
4198
|
if ignore_flush:
|
|
@@ -386,7 +386,10 @@ class LifecycleRuleSetStorageClass(dict):
|
|
|
386
386
|
def __init__(self, storage_class, **kw):
|
|
387
387
|
conditions = LifecycleRuleConditions(**kw)
|
|
388
388
|
rule = {
|
|
389
|
-
"action": {
|
|
389
|
+
"action": {
|
|
390
|
+
"type": "SetStorageClass",
|
|
391
|
+
"storageClass": storage_class,
|
|
392
|
+
},
|
|
390
393
|
"condition": dict(conditions),
|
|
391
394
|
}
|
|
392
395
|
super().__init__(rule)
|
|
@@ -846,6 +849,7 @@ class Bucket(_PropertyMixin):
|
|
|
846
849
|
encryption_key=None,
|
|
847
850
|
kms_key_name=None,
|
|
848
851
|
generation=None,
|
|
852
|
+
crc32c_checksum=None,
|
|
849
853
|
):
|
|
850
854
|
"""Factory constructor for blob object.
|
|
851
855
|
|
|
@@ -873,6 +877,14 @@ class Bucket(_PropertyMixin):
|
|
|
873
877
|
:param generation: (Optional) If present, selects a specific revision of
|
|
874
878
|
this object.
|
|
875
879
|
|
|
880
|
+
:type crc32c_checksum: str
|
|
881
|
+
:param crc32c_checksum:
|
|
882
|
+
(Optional) If set, the CRC32C checksum of the blob's content.
|
|
883
|
+
CRC32c checksum, as described in RFC 4960, Appendix B; encoded using
|
|
884
|
+
base64 in big-endian byte order. See
|
|
885
|
+
Apenndix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B
|
|
886
|
+
base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4
|
|
887
|
+
|
|
876
888
|
:rtype: :class:`google.cloud.storage.blob.Blob`
|
|
877
889
|
:returns: The blob object created.
|
|
878
890
|
"""
|
|
@@ -883,6 +895,7 @@ class Bucket(_PropertyMixin):
|
|
|
883
895
|
encryption_key=encryption_key,
|
|
884
896
|
kms_key_name=kms_key_name,
|
|
885
897
|
generation=generation,
|
|
898
|
+
crc32c_checksum=crc32c_checksum,
|
|
886
899
|
)
|
|
887
900
|
|
|
888
901
|
def notification(
|
|
@@ -3253,7 +3266,10 @@ class Bucket(_PropertyMixin):
|
|
|
3253
3266
|
:type not_found_page: str
|
|
3254
3267
|
:param not_found_page: The file to use when a page isn't found.
|
|
3255
3268
|
"""
|
|
3256
|
-
data = {
|
|
3269
|
+
data = {
|
|
3270
|
+
"mainPageSuffix": main_page_suffix,
|
|
3271
|
+
"notFoundPage": not_found_page,
|
|
3272
|
+
}
|
|
3257
3273
|
self._patch_property("website", data)
|
|
3258
3274
|
|
|
3259
3275
|
def disable_website(self):
|
|
@@ -3385,7 +3401,11 @@ class Bucket(_PropertyMixin):
|
|
|
3385
3401
|
return Policy.from_api_repr(info)
|
|
3386
3402
|
|
|
3387
3403
|
def test_iam_permissions(
|
|
3388
|
-
self,
|
|
3404
|
+
self,
|
|
3405
|
+
permissions,
|
|
3406
|
+
client=None,
|
|
3407
|
+
timeout=_DEFAULT_TIMEOUT,
|
|
3408
|
+
retry=DEFAULT_RETRY,
|
|
3389
3409
|
):
|
|
3390
3410
|
"""API call: test permissions
|
|
3391
3411
|
|
{google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/google_cloud_storage.egg-info/SOURCES.txt
RENAMED
|
@@ -61,6 +61,7 @@ tests/conformance/retry_strategy_test_data.json
|
|
|
61
61
|
tests/conformance/test_conformance.py
|
|
62
62
|
tests/data/CloudPlatform_128px_Retina.png
|
|
63
63
|
tests/data/five-point-one-mb-file.zip
|
|
64
|
+
tests/data/random_9_MiB_file
|
|
64
65
|
tests/data/simple.txt
|
|
65
66
|
tests/perf/README.md
|
|
66
67
|
tests/perf/_perf_utils.py
|
|
Binary file
|
|
@@ -42,6 +42,11 @@ EXAMPLE_XML_MPU_INITIATE_TEXT_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"
|
|
|
42
42
|
UPLOAD_ID = "VXBsb2FkIElEIGZvciBlbHZpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZA"
|
|
43
43
|
PARTS = {1: "39a59594290b0f9a30662a56d695b71d", 2: "00000000290b0f9a30662a56d695b71d"}
|
|
44
44
|
FILE_DATA = b"testdata" * 128
|
|
45
|
+
_HASH_HEADER = "x-goog-hash"
|
|
46
|
+
CRC32C_HASH_OF_FIRST_PART = "8hVqVQ=="
|
|
47
|
+
MD5_HASH_OF_FIRST_PART = "gfVZ4+0LdooJwGAkxLrCcg=="
|
|
48
|
+
DEFAULT_CONNECT_TIMEOUT = 61
|
|
49
|
+
DEFAULT_READ_TIMEOUT = 60
|
|
45
50
|
|
|
46
51
|
|
|
47
52
|
@pytest.fixture(scope="session")
|
|
@@ -402,6 +407,66 @@ def test_mpu_part(filename):
|
|
|
402
407
|
assert part.etag == PARTS[1]
|
|
403
408
|
|
|
404
409
|
|
|
410
|
+
def test_mpu_part_with_md5_enabled(filename):
|
|
411
|
+
part = upload_mod.XMLMPUPart(
|
|
412
|
+
EXAMPLE_XML_UPLOAD_URL,
|
|
413
|
+
UPLOAD_ID,
|
|
414
|
+
filename,
|
|
415
|
+
start=0,
|
|
416
|
+
end=128,
|
|
417
|
+
part_number=1,
|
|
418
|
+
checksum="md5",
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
transport = mock.Mock(spec=["request"])
|
|
422
|
+
transport.request.return_value = _make_response(
|
|
423
|
+
headers={"etag": PARTS[1], _HASH_HEADER: f"md5={MD5_HASH_OF_FIRST_PART}"}
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
part.upload(transport)
|
|
427
|
+
|
|
428
|
+
transport.request.assert_called_once_with(
|
|
429
|
+
"PUT",
|
|
430
|
+
f"{part.upload_url}?partNumber={part.part_number}&uploadId={UPLOAD_ID}",
|
|
431
|
+
data=FILE_DATA[part.start : part.end],
|
|
432
|
+
headers={"X-Goog-Hash": f"md5={MD5_HASH_OF_FIRST_PART}"},
|
|
433
|
+
timeout=(DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT),
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
assert part.finished
|
|
437
|
+
assert part.etag == PARTS[1]
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def test_mpu_part_with_crc32c_enabled(filename):
|
|
441
|
+
part = upload_mod.XMLMPUPart(
|
|
442
|
+
EXAMPLE_XML_UPLOAD_URL,
|
|
443
|
+
UPLOAD_ID,
|
|
444
|
+
filename,
|
|
445
|
+
start=0,
|
|
446
|
+
end=128,
|
|
447
|
+
part_number=1,
|
|
448
|
+
checksum="crc32c",
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
transport = mock.Mock(spec=["request"])
|
|
452
|
+
transport.request.return_value = _make_response(
|
|
453
|
+
headers={"etag": PARTS[1], _HASH_HEADER: f"crc32c={CRC32C_HASH_OF_FIRST_PART}"}
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
part.upload(transport)
|
|
457
|
+
|
|
458
|
+
transport.request.assert_called_once_with(
|
|
459
|
+
"PUT",
|
|
460
|
+
f"{part.upload_url}?partNumber={part.part_number}&uploadId={UPLOAD_ID}",
|
|
461
|
+
data=FILE_DATA[part.start : part.end],
|
|
462
|
+
headers={"X-Goog-Hash": f"crc32c={CRC32C_HASH_OF_FIRST_PART}"},
|
|
463
|
+
timeout=(DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT),
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
assert part.finished
|
|
467
|
+
assert part.etag == PARTS[1]
|
|
468
|
+
|
|
469
|
+
|
|
405
470
|
def _make_response(status_code=http.client.OK, headers=None, text=None):
|
|
406
471
|
headers = headers or {}
|
|
407
472
|
return mock.Mock(
|
{google_cloud_storage-3.3.0 → google_cloud_storage-3.3.1}/tests/resumable_media/unit/test__upload.py
RENAMED
|
@@ -47,6 +47,21 @@ EXAMPLE_XML_MPU_INITIATE_TEXT_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"
|
|
|
47
47
|
UPLOAD_ID = "VXBsb2FkIElEIGZvciBlbHZpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZA"
|
|
48
48
|
PARTS = {1: "39a59594290b0f9a30662a56d695b71d", 2: "00000000290b0f9a30662a56d695b71d"}
|
|
49
49
|
FILE_DATA = b"testdata" * 128
|
|
50
|
+
CHECKSUM_MISMATCH_ERROR_MSG_XML_TEMPLATE = """<?xml version='1.0' encoding='UTF-8'?>
|
|
51
|
+
<Error>
|
|
52
|
+
<Code>{ERROR_CODE}</Code>
|
|
53
|
+
<Message>The MD5 you specified in Content-MD5 or x-goog-hash was invalid.</Message>
|
|
54
|
+
<Details>Invalid MD5 value: dfdfdfd==</Details>
|
|
55
|
+
</Error>"""
|
|
56
|
+
INVALID_MD5_XML_RESPONSE = CHECKSUM_MISMATCH_ERROR_MSG_XML_TEMPLATE.format(
|
|
57
|
+
ERROR_CODE="InvalidDigest"
|
|
58
|
+
)
|
|
59
|
+
INVALID_CRC32C_XML_RESPONSE = CHECKSUM_MISMATCH_ERROR_MSG_XML_TEMPLATE.format(
|
|
60
|
+
ERROR_CODE="BadDigest"
|
|
61
|
+
)
|
|
62
|
+
INCORRECT_LENGTH_CRC32C_XML_RESPONSE = CHECKSUM_MISMATCH_ERROR_MSG_XML_TEMPLATE.format(
|
|
63
|
+
ERROR_CODE="CrcMismatch"
|
|
64
|
+
)
|
|
50
65
|
|
|
51
66
|
|
|
52
67
|
@pytest.fixture(scope="session")
|
|
@@ -1471,7 +1486,15 @@ def test_xml_mpu_part_invalid_response(filename):
|
|
|
1471
1486
|
part._process_upload_response(response)
|
|
1472
1487
|
|
|
1473
1488
|
|
|
1474
|
-
|
|
1489
|
+
@pytest.mark.parametrize(
|
|
1490
|
+
"error_scenarios",
|
|
1491
|
+
[
|
|
1492
|
+
INVALID_MD5_XML_RESPONSE,
|
|
1493
|
+
INVALID_CRC32C_XML_RESPONSE,
|
|
1494
|
+
INCORRECT_LENGTH_CRC32C_XML_RESPONSE,
|
|
1495
|
+
],
|
|
1496
|
+
)
|
|
1497
|
+
def test_xml_mpu_part_checksum_failure(filename, error_scenarios):
|
|
1475
1498
|
PART_NUMBER = 1
|
|
1476
1499
|
START = 0
|
|
1477
1500
|
END = 256
|
|
@@ -1490,7 +1513,9 @@ def test_xml_mpu_part_checksum_failure(filename):
|
|
|
1490
1513
|
_fix_up_virtual(part)
|
|
1491
1514
|
part._prepare_upload_request()
|
|
1492
1515
|
response = _make_xml_response(
|
|
1493
|
-
|
|
1516
|
+
status_code=http.client.BAD_REQUEST,
|
|
1517
|
+
headers={"etag": ETAG, "x-goog-hash": "md5=Ojk9c3dhfxgoKVVHYwFbHQ=="},
|
|
1518
|
+
text=error_scenarios,
|
|
1494
1519
|
) # Example md5 checksum but not the correct one
|
|
1495
1520
|
with pytest.raises(DataCorruption):
|
|
1496
1521
|
part._process_upload_response(response)
|
|
@@ -1555,7 +1580,7 @@ def _make_xml_response(status_code=http.client.OK, headers=None, text=None):
|
|
|
1555
1580
|
headers=headers,
|
|
1556
1581
|
status_code=status_code,
|
|
1557
1582
|
text=text,
|
|
1558
|
-
spec=["headers", "status_code"],
|
|
1583
|
+
spec=["headers", "status_code", "text"],
|
|
1559
1584
|
)
|
|
1560
1585
|
|
|
1561
1586
|
|
|
@@ -59,9 +59,7 @@ def _create_signed_list_blobs_url_helper(
|
|
|
59
59
|
:Response headers end."
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
def test_create_signed_list_blobs_url_v2(
|
|
63
|
-
storage_client, signing_bucket, no_mtls
|
|
64
|
-
):
|
|
62
|
+
def test_create_signed_list_blobs_url_v2(storage_client, signing_bucket, no_mtls):
|
|
65
63
|
_create_signed_list_blobs_url_helper(
|
|
66
64
|
storage_client,
|
|
67
65
|
signing_bucket,
|
|
@@ -83,9 +81,7 @@ def test_create_signed_list_blobs_url_v2_w_expiration(
|
|
|
83
81
|
)
|
|
84
82
|
|
|
85
83
|
|
|
86
|
-
def test_create_signed_list_blobs_url_v4(
|
|
87
|
-
storage_client, signing_bucket, no_mtls
|
|
88
|
-
):
|
|
84
|
+
def test_create_signed_list_blobs_url_v4(storage_client, signing_bucket, no_mtls):
|
|
89
85
|
_create_signed_list_blobs_url_helper(
|
|
90
86
|
storage_client,
|
|
91
87
|
signing_bucket,
|
|
@@ -229,9 +225,7 @@ def test_create_signed_read_url_v4_w_non_ascii_name(
|
|
|
229
225
|
)
|
|
230
226
|
|
|
231
227
|
|
|
232
|
-
def test_create_signed_read_url_v2_w_csek(
|
|
233
|
-
storage_client, signing_bucket, no_mtls
|
|
234
|
-
):
|
|
228
|
+
def test_create_signed_read_url_v2_w_csek(storage_client, signing_bucket, no_mtls):
|
|
235
229
|
encryption_key = os.urandom(32)
|
|
236
230
|
_create_signed_read_url_helper(
|
|
237
231
|
storage_client,
|
|
@@ -242,9 +236,7 @@ def test_create_signed_read_url_v2_w_csek(
|
|
|
242
236
|
)
|
|
243
237
|
|
|
244
238
|
|
|
245
|
-
def test_create_signed_read_url_v4_w_csek(
|
|
246
|
-
storage_client, signing_bucket, no_mtls
|
|
247
|
-
):
|
|
239
|
+
def test_create_signed_read_url_v4_w_csek(storage_client, signing_bucket, no_mtls):
|
|
248
240
|
encryption_key = os.urandom(32)
|
|
249
241
|
_create_signed_read_url_helper(
|
|
250
242
|
storage_client,
|
|
@@ -327,9 +319,7 @@ def test_create_signed_read_url_v4_w_access_token_universe_domain(
|
|
|
327
319
|
"https://www.googleapis.com/auth/devstorage.read_write",
|
|
328
320
|
"https://www.googleapis.com/auth/iam",
|
|
329
321
|
]
|
|
330
|
-
response = universe_domain_iam_client.generate_access_token(
|
|
331
|
-
name=name, scope=scope
|
|
332
|
-
)
|
|
322
|
+
response = universe_domain_iam_client.generate_access_token(name=name, scope=scope)
|
|
333
323
|
|
|
334
324
|
_create_signed_read_url_helper(
|
|
335
325
|
universe_domain_client,
|
|
@@ -340,9 +330,7 @@ def test_create_signed_read_url_v4_w_access_token_universe_domain(
|
|
|
340
330
|
)
|
|
341
331
|
|
|
342
332
|
|
|
343
|
-
def _create_signed_delete_url_helper(
|
|
344
|
-
client, bucket, version="v2", expiration=None
|
|
345
|
-
):
|
|
333
|
+
def _create_signed_delete_url_helper(client, bucket, version="v2", expiration=None):
|
|
346
334
|
expiration = _morph_expiration(version, expiration)
|
|
347
335
|
|
|
348
336
|
blob = bucket.blob("DELETE_ME.txt")
|
|
@@ -372,9 +360,7 @@ def test_create_signed_delete_url_v2(storage_client, signing_bucket, no_mtls):
|
|
|
372
360
|
|
|
373
361
|
|
|
374
362
|
def test_create_signed_delete_url_v4(storage_client, signing_bucket, no_mtls):
|
|
375
|
-
_create_signed_delete_url_helper(
|
|
376
|
-
storage_client, signing_bucket, version="v4"
|
|
377
|
-
)
|
|
363
|
+
_create_signed_delete_url_helper(storage_client, signing_bucket, version="v4")
|
|
378
364
|
|
|
379
365
|
|
|
380
366
|
def _create_signed_resumable_upload_url_helper(
|
|
@@ -393,9 +379,7 @@ def _create_signed_resumable_upload_url_helper(
|
|
|
393
379
|
)
|
|
394
380
|
|
|
395
381
|
post_headers = {"x-goog-resumable": "start"}
|
|
396
|
-
post_response = requests.post(
|
|
397
|
-
signed_resumable_upload_url, headers=post_headers
|
|
398
|
-
)
|
|
382
|
+
post_response = requests.post(signed_resumable_upload_url, headers=post_headers)
|
|
399
383
|
assert (
|
|
400
384
|
post_response.status_code == 201
|
|
401
385
|
), f"Response content start: {post_response.content} \
|
|
@@ -445,9 +429,7 @@ def _create_signed_resumable_upload_url_helper(
|
|
|
445
429
|
:Response headers end."
|
|
446
430
|
|
|
447
431
|
|
|
448
|
-
def test_create_signed_resumable_upload_url_v2(
|
|
449
|
-
storage_client, signing_bucket, no_mtls
|
|
450
|
-
):
|
|
432
|
+
def test_create_signed_resumable_upload_url_v2(storage_client, signing_bucket, no_mtls):
|
|
451
433
|
_create_signed_resumable_upload_url_helper(
|
|
452
434
|
storage_client,
|
|
453
435
|
signing_bucket,
|
|
@@ -455,9 +437,7 @@ def test_create_signed_resumable_upload_url_v2(
|
|
|
455
437
|
)
|
|
456
438
|
|
|
457
439
|
|
|
458
|
-
def test_create_signed_resumable_upload_url_v4(
|
|
459
|
-
storage_client, signing_bucket, no_mtls
|
|
460
|
-
):
|
|
440
|
+
def test_create_signed_resumable_upload_url_v4(storage_client, signing_bucket, no_mtls):
|
|
461
441
|
_create_signed_resumable_upload_url_helper(
|
|
462
442
|
storage_client,
|
|
463
443
|
signing_bucket,
|
|
@@ -494,9 +474,7 @@ def test_generate_signed_post_policy_v4(
|
|
|
494
474
|
)
|
|
495
475
|
with open(blob_name, "r") as f:
|
|
496
476
|
files = {"file": (blob_name, f)}
|
|
497
|
-
response = requests.post(
|
|
498
|
-
policy["url"], data=policy["fields"], files=files
|
|
499
|
-
)
|
|
477
|
+
response = requests.post(policy["url"], data=policy["fields"], files=files)
|
|
500
478
|
|
|
501
479
|
os.remove(blob_name)
|
|
502
480
|
assert (
|
|
@@ -549,9 +527,7 @@ def test_generate_signed_post_policy_v4_access_token_sa_email(
|
|
|
549
527
|
)
|
|
550
528
|
with open(blob_name, "r") as f:
|
|
551
529
|
files = {"file": (blob_name, f)}
|
|
552
|
-
response = requests.post(
|
|
553
|
-
policy["url"], data=policy["fields"], files=files
|
|
554
|
-
)
|
|
530
|
+
response = requests.post(policy["url"], data=policy["fields"], files=files)
|
|
555
531
|
|
|
556
532
|
os.remove(blob_name)
|
|
557
533
|
assert (
|
|
@@ -591,9 +567,7 @@ def test_generate_signed_post_policy_v4_invalid_field(
|
|
|
591
567
|
)
|
|
592
568
|
with open(blob_name, "r") as f:
|
|
593
569
|
files = {"file": (blob_name, f)}
|
|
594
|
-
response = requests.post(
|
|
595
|
-
policy["url"], data=policy["fields"], files=files
|
|
596
|
-
)
|
|
570
|
+
response = requests.post(policy["url"], data=policy["fields"], files=files)
|
|
597
571
|
|
|
598
572
|
os.remove(blob_name)
|
|
599
573
|
assert (
|