diff --git a/smart_open/gcs.py b/smart_open/gcs.py index dc0e5042..4b105528 100644 --- a/smart_open/gcs.py +++ b/smart_open/gcs.py @@ -15,6 +15,7 @@ import google.cloud.exceptions import google.cloud.storage import google.auth.transport.requests + _PREDEFINED_ACL_SUPPORTED = google.cloud.storage.__version__.split('.') >= ['2', '6'] except ImportError: MISSING_DEPS = True @@ -420,14 +421,20 @@ def __init__( self._session = google.auth.transport.requests.AuthorizedSession(client._credentials) + upload_kwargs = {} + if blob_properties: + if 'predefined_acl' in blob_properties: + upload_kwargs['predefined_acl'] = blob_properties.pop('predefined_acl') for k, v in blob_properties.items(): setattr(self._blob, k, v) + if 'predefined_acl' in upload_kwargs and not _PREDEFINED_ACL_SUPPORTED: + raise NotImplementedError('GCS "predefined_acl" requires google-cloud-storage>=2.6.0') # # https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload#start-resumable # - self._resumable_upload_url = self._blob.create_resumable_upload_session() + self._resumable_upload_url = self._blob.create_resumable_upload_session(**upload_kwargs) # # This member is part of the io.BufferedIOBase interface. diff --git a/smart_open/tests/test_gcs.py b/smart_open/tests/test_gcs.py index 22eb7f40..451db59d 100644 --- a/smart_open/tests/test_gcs.py +++ b/smart_open/tests/test_gcs.py @@ -142,12 +142,13 @@ def __init__(self, name, bucket): self._create_if_not_exists() - def create_resumable_upload_session(self): + def create_resumable_upload_session(self, predefined_acl=None): resumeable_upload_url = RESUMABLE_SESSION_URI_TEMPLATE % dict( bucket=self._bucket.name, upload_id=str(uuid.uuid4()), ) upload = FakeBlobUpload(resumeable_upload_url, self) + self.acl = predefined_acl self._bucket.register_upload(upload) return resumeable_upload_url @@ -807,12 +808,14 @@ def test_write_05(self): smart_open_write = smart_open.gcs.Writer(BUCKET_NAME, WRITE_BLOB_NAME, blob_properties={ "content_type": "random/x-test", - "content_encoding": "coded" + "content_encoding": "coded", + "predefined_acl": "publicRead" } ) with smart_open_write as fout: # noqa assert fout._blob.content_type == "random/x-test" assert fout._blob.content_encoding == "coded" + assert fout._blob.acl == "publicRead" def test_gzip(self): expected = u'а не спеть ли мне песню... о любви'.encode('utf-8')