1

I hope somebody can help with this issue which is confusing me a bit.

I am trying to make a back up copy script for a storage container. What I am trying to achieve, is to copy the content of a container from container A to container B.

Just to make my case scenario clear, this is the structure of my storages.

Storage A:

storageaccountout 
 |--- Containers
   |---- new blob
     |---newfile.txt

In Storage account A I have a container called newblob and in this blob I have just one file.

On the other had I have storage B

Storage B:

Storageaccountin
  |--- Containers
    

Storage B has nothing, just the default blob $logs

What I am trying to do, is to copy the container A blob, into container B blob.

I have this script:

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


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


# Target Client
target_connection_string = 'connection-string'
target_account_key = 'key'
source_container_name = source_container_name
target_blob_name = 'newfile.txt'
target_destination_blob = 'newblob'
# Create client
client = BlobServiceClient.from_connection_string(connection_string) 

# Create target client
target_client = BlobServiceClient.from_connection_string(target_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= AccountSasPermissions(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
)


# target client

target_sas_token = generate_account_sas(
    account_name = target_client.account_name,
    account_key = target_account_key, 
    resource_types = ResourceTypes(object=True, container=True),
    permission= AccountSasPermissions(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(
    target_client.url,
    container_name = source_container_name, 
    blob_name = target_blob_name,
    credential = target_sas_token
)

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

Now When I run this script, I get the following error:

Traceback (most recent call last):
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_blob_client.py", line 1922, in start_copy_from_url
    return self._client.blob.start_copy_from_url(**options)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_generated/operations/_blob_operations.py", line 2280, in start_copy_from_url
    raise HttpResponseError(response=response, model=error)
azure.core.exceptions.HttpResponseError: Operation returned an invalid status 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/user/Desktop/AzCopy/blob.py", line 35, in <module>
    new_blob.start_copy_from_url(source_blob.url)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/core/tracing/decorator.py", line 83, in wrapper_use_tracer
    return func(*args, **kwargs)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_blob_client.py", line 1924, in start_copy_from_url
    process_storage_error(error)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_shared/response_handlers.py", line 150, in process_storage_error
    error.raise_with_traceback()
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/core/exceptions.py", line 247, in raise_with_traceback
    raise super(AzureError, self).with_traceback(self.exc_traceback)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_blob_client.py", line 1922, in start_copy_from_url
    return self._client.blob.start_copy_from_url(**options)
  File "/Users/user/miniforge3/lib/python3.9/site-packages/azure/storage/blob/_generated/operations/_blob_operations.py", line 2280, in start_copy_from_url
    raise HttpResponseError(response=response, model=error)
azure.core.exceptions.ResourceNotFoundError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:199c7c8a-501e-00a3-7418-aed966000000
Time:2021-09-20T12:08:20.0231825Z
ErrorCode:CannotVerifyCopySource
Error:None

As far as I understand, this is an error with the Share Access Signature, but how is this working if I am giving the connection string and the storage key, how come I am getting this error.

Thank you so much for any help you can provide me with and please, if you need more info do not hesitate to ask

7
  • Please try by removing the following from your sas token generation code: start = datetime.now(),. Commented Sep 20, 2021 at 13:00
  • Thank you so much for your reply. I tried removing the line you advised, but I get a new error azure.core.exceptions.ResourceNotFoundError: Operation returned an invalid status 'The specified container does not exist.' Commented Sep 20, 2021 at 13:07
  • Does both source and target blob container exist? Commented Sep 20, 2021 at 13:08
  • Mmm I fixed the code to make it work. I was missing the container where to copy the content. Maybe you can help me to solve this problem, but I was looking to something about how to copy from container (storage account A) into a totally difference storage account. Is this doable? thank you so much for any help. Because with the actual code I can only copy from container to container into the same storage account Commented Sep 20, 2021 at 13:11
  • I was looking to something about how to copy from container (storage account A) into a totally difference storage account. Is this doable? - This is entirely doable. What you would need to do is create a client for your target storage account (let's call it target_client and then use that instead of client here: new_blob = client.get_blob_client(destination_container_name, blob_name). Commented Sep 20, 2021 at 13:13

1 Answer 1

3

Thank you so much to @GauravMantri for his patience and help.

The solution to copy blob storage from one container to another is as follow:

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




#================================ SOURCE ===============================
# Source Client
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= AccountSasPermissions(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
)


# ============================= TARGET =======================================

# Target Client
target_connection_string = ''
target_account_key = ''
source_container_name = source_container_name
target_blob_name = ''
target_destination_blob = ''

# Create target client
target_client = BlobServiceClient.from_connection_string(target_connection_string)


# Create new blob and start copy operation.
# new_blob = client.get_blob_client(destination_container_name, blob_name)    
new_blob = target_client.get_blob_client(target_destination_blob, target_blob_name)    
new_blob.start_copy_from_url(source_blob.url)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.