Skip to content

Commit 23512ea

Browse files
davidebellonitseaver
authored andcommitted
Storage: support 'sourceGeneration' in 'copy_blob' (googleapis#4546)
Closes googleapis#4533.
1 parent 76a0f5a commit 23512ea

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

storage/google/cloud/storage/bucket.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ def delete_blobs(self, blobs, on_error=None, client=None):
654654
raise
655655

656656
def copy_blob(self, blob, destination_bucket, new_name=None,
657-
client=None, preserve_acl=True):
657+
client=None, preserve_acl=True, source_generation=None):
658658
"""Copy the given blob to the given bucket, optionally with a new name.
659659
660660
If :attr:`user_project` is set, bills the API request to that project.
@@ -678,6 +678,10 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
678678
:param preserve_acl: Optional. Copies ACL from old blob to new blob.
679679
Default: True.
680680
681+
:type source_generation: long
682+
:param source_generation: Optional. The generation of the blob to be
683+
copied.
684+
681685
:rtype: :class:`google.cloud.storage.blob.Blob`
682686
:returns: The new Blob.
683687
"""
@@ -687,6 +691,9 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
687691
if self.user_project is not None:
688692
query_params['userProject'] = self.user_project
689693

694+
if source_generation is not None:
695+
query_params['sourceGeneration'] = source_generation
696+
690697
if new_name is None:
691698
new_name = blob.name
692699

storage/tests/unit/test_bucket.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,31 @@ class _Blob(object):
728728
self.assertEqual(kw['path'], COPY_PATH)
729729
self.assertEqual(kw['query_params'], {})
730730

731+
def test_copy_blobs_source_generation(self):
732+
SOURCE = 'source'
733+
DEST = 'dest'
734+
BLOB_NAME = 'blob-name'
735+
GENERATION = 1512565576797178
736+
737+
class _Blob(object):
738+
name = BLOB_NAME
739+
path = '/b/%s/o/%s' % (SOURCE, BLOB_NAME)
740+
741+
connection = _Connection({})
742+
client = _Client(connection)
743+
source = self._make_one(client=client, name=SOURCE)
744+
dest = self._make_one(client=client, name=DEST)
745+
blob = _Blob()
746+
new_blob = source.copy_blob(blob, dest, source_generation=GENERATION)
747+
self.assertIs(new_blob.bucket, dest)
748+
self.assertEqual(new_blob.name, BLOB_NAME)
749+
kw, = connection._requested
750+
COPY_PATH = '/b/%s/o/%s/copyTo/b/%s/o/%s' % (SOURCE, BLOB_NAME,
751+
DEST, BLOB_NAME)
752+
self.assertEqual(kw['method'], 'POST')
753+
self.assertEqual(kw['path'], COPY_PATH)
754+
self.assertEqual(kw['query_params'], {'sourceGeneration' : GENERATION})
755+
731756
def test_copy_blobs_preserve_acl(self):
732757
from google.cloud.storage.acl import ObjectACL
733758

0 commit comments

Comments
 (0)