5

I have been referring to the document https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python. I have not been able to find the proper APIs for copy/move a file from one container to another container. Let's say I have two containers A and B. Now I want to copy a blob from A to B. How can I achieve this? An example will be appreciated.

Library details:

azure-core==1.1.1
azure-storage-blob==12.0.0

Note: I have been through this thread which is supported only in older version of the SDK.

Paolo
  • 21,270
  • 6
  • 38
  • 69
kanchan
  • 65
  • 1
  • 5

2 Answers2

6

Here's a full example for version 12.0.0 of the SDK:

from azure.storage.blob import BlobClient, BlobServiceClient
from azure.storage.blob import ResourceTypes, AccountSasPermissions
from azure.storage.blob import generate_account_sas    

connection_string = '' # The connection string for the source container
account_key = '' # The account key for the source container
source_container_name = '' # Name of container which has blob to be copied
blob_name = '' # Name of the blob you want to copy
destination_container_name = '' # Name of container where blob will be copied

# Create client
client = BlobServiceClient.from_connection_string(connection_string) 

# Create sas token for blob
sas_token = generate_account_sas(
    account_name = client.account_name,
    account_key = account_key 
    resource_types = ResourceTypes(object=True, container=True),
    permission= AccountSasPermission(read=True,list=True),
    start = datetime.now()
    expiry = datetime.utcnow() + timedelta(hours=4) # Token valid for 4 hours
)

# Create blob client for source blob
source_blob = BlobClient(
    client.url,
    container_name = source_container_name, 
    blob_name = blob_name,
    credential = sas_token
)

# Create new blob and start copy operation.
new_blob = client.get_blob_client(destination_container_name, blob_name)    
new_blob.start_copy_from_url(source_blob.url)

See here for more information on how you can get the connection string and access key for the container.


This answer assumes that both containers are within the same subscription.

Paolo
  • 21,270
  • 6
  • 38
  • 69
  • Thanks a lot for the answer. It worked for me. However could you please let me know where you got to know about the class variable 'url'? I have followed the document in https://learn.microsoft.com/en-us/python/api/azure-storage-blob/azure.storage.blob.blobclient?view=azure-python but could not find it. – kanchan Dec 06 '19 at 09:28
  • @kanchan You are welcome, glad you found the answer useful. I must have found the url property by inspecting the objects. See [here](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py#L71): it expects the storage account URI. It just so happens that the client has a property with that endpoint, so it's handy to use that directly. – Paolo Dec 06 '19 at 09:39
  • yes I could see the variable by dumping the object. What I am worried about is as this class variable is not exposed in API reference what if my code breaks in the future. Just being curious, is there any alternative for the method existed in older SDK "make_blob_url" in the latest SDK? – kanchan Dec 06 '19 at 10:50
  • @kanchan I understand your concern, but if you don't change the SDK version then it won't break in the future. Anyway, that URI points to the storage account where the source container is stored, e.g `f'https://{mystorageaccount}.blob.core.windows.net/'` so you can get that string pretty easily. – Paolo Dec 06 '19 at 10:57
1

You should take a look at start_copy_from_url method in the SDK.

From the same link:

# Get the blob client with the source blob
source_blob = "<source-blob-url>"
copied_blob = blob_service_client.get_blob_client("<target-container>", '<blob-name>')

# start copy and check copy status
copy = copied_blob.start_copy_from_url(source_blob)
props = copied_blob.get_blob_properties()
print(props.copy.status)
Marius Mucenicu
  • 1,685
  • 2
  • 16
  • 25
Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241