How to upload a file in a nested directory to Storage accounts File Share service using Python SDK ?

Vaibhav Jain 40 Reputation points
2023-07-24T05:30:39.9633333+00:00

I am trying to upload a file to the path, using ShareDirectoryClient Class of Azure Python SDK.
I have attached below the code and errors that I am getting.

path = "users/vaibhav11/projects/assets/fbx"
directories = path.lower().strip("/").split("/")
for directory in directories:
	try:    
		directory_client = directory_client.get_subdirectory_client(directory)
		if not directory_client.exists():
			directory_client.create_directory()
	except Exception as e:
		print(e.args)

with directory_client.get_file_client(file_name=upload_file.name) as file_client:
	file_client.upload_file(data = file_content, length=len(file_content))
	print("Uploaded")

The "directory_client" is an object of ShareDirectoryClient, which is used in the above code snippet to create directories. The problem faced is, with every directory that is being created I get the below Exception.

('The specifed resource name contains invalid characters.\nRequestId:fc43b173-e01a-000c-1ae8-bd388a000000\nTime:2023-07-24T04:37:52.5072468Z\nErrorCode:InvalidResourceName',)

ClientAuthenticationError

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. 
ErrorCode:AuthenticationFailed authenticationerrordetail:The MAC signature found in the HTTP request 'E0eObuCq+OdHAtf4qG80kb3wprxR4vwIsDpjinnVvUM=' is not the same as any computed signature. Server used following string to sign: 'PUT.......'

And sometimes I even get ClientAuthenticationError. I'm not really sure, what is creating the problem in both the cases.

Any solutions and suggestions are open.

Thanks!

Azure Files
Azure Files
An Azure service that offers file shares in the cloud.
1,424 questions
Azure Storage
Azure Storage
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
3,539 questions
0 comments No comments
{count} votes

Accepted answer
  1. Sumarigo-MSFT 47,471 Reputation points Microsoft Employee Moderator
    2023-07-28T05:23:28.0266667+00:00

    @Vaibhav Jain Welcome to Microsoft Q&A Forum, Thank you for posting your query here!

    Based on the code and errors provided, it seems like there are two separate issues that need to be addressed:

    Initially, try creating directories inside File Share directly, but first, make sure that there is already an existing directory. Try adding the file share with the root folder

    1. Invalid characters in resource name: The error message 'The specified resource name contains invalid characters.' suggests that there might be an issue with the directory names you are trying to create. Azure has certain restrictions on resource names, and they must adhere to the rules outlined by Azure.

    Azure naming rules for directories and files:

    • Must start with a letter or number.
    • Can only contain letters, numbers, periods (.), hyphens (-), and underscores (_).
    • Must be between 3 and 63 characters long.
    • Directory and file names are case-preserving and case-insensitive.
    • Directory and file component names must be no more than 255 characters in length.
    • Directory names cannot end with the forward slash character (/). If provided, it will be automatically removed.
    • File names must not end with the forward slash character (/).
    • Reserved URL characters must be properly escaped.
    • The following characters are not allowed: " \ / : | < > * ?

    For detailed information, refer to this article: https://learn.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-shares--directories--files--and-metadata

    Make sure that the directories you are trying to create follow these rules, especially regarding special characters.

    1. Authentication errors: The errors 'Server failed to authenticate the request' and 'ClientAuthenticationError' indicate that there is an issue with the authentication process while trying to upload the file.

    To resolve this, ensure that you have properly set up the authentication for your Azure Python SDK. Double-check the authentication credentials and the correct configuration of your storage account and access keys. The Authorization header should be formed correctly with the valid signature.

    Here are some troubleshooting steps to follow:

    • Verify that your storage account name and key (or connection string) are correct.
    • Check if there are any typos or mistakes in the credentials you are using.
    • Ensure that the system time on your machine is accurate, as incorrect time settings can lead to authentication failures.

    If you are using the Azure.Identity library for authentication, ensure that it is correctly configured and providing valid credentials.

    Once you have addressed both issues, your code should work as expected, creating directories and uploading the file to the specified path in your Azure storage account.

    Regarding the "ClientAuthenticationError", this error usually occurs when the authentication credentials are incorrect or expired. Please make sure that you have provided the correct account name and account key or connection string in your code. You can also try regenerating the account key or connection string and updating your code with the new credentials.

    Now, you can use the ShareDirectoryClient and ShareFileClient classes to upload the file to the desired nested directory.

    Upload the file to the nested directory:

    # Specify the path to the nested directory where you want to upload the file
    path = "users/vaibhav11/projects/assets/fbx"
    
    # Split the path into individual directory names
    directories = path.lower().strip("/").split("/")
    
    # Create the ShareDirectoryClient for the root directory
    share_directory_client = ShareDirectoryClient.from_connection_string(
        conn_str=f"DefaultEndpointsProtocol=https;AccountName={storage_account_name};AccountKey={storage_account_key}",
        share_name="your_share_name",  # Replace with the name of your Azure File Share
        directory_path=""
    )
    
    # Create nested directories (if they don't exist) and upload the file
    for directory in directories:
        try:
            # Get the ShareDirectoryClient for the current directory
            share_directory_client = share_directory_client.get_subdirectory_client(directory)
            if not share_directory_client.exists():
                share_directory_client.create_directory()
        except Exception as e:
            print("Error:", e)
    
    # Replace "local_file_path" with the path to the file you want to upload
    local_file_path = "path/to/your/local/file.ext"
    file_name = "file.ext"  # Replace with the desired name for the file in the Azure File Share
    
    # Upload the file to the final nested directory
    with ShareFileClient.from_connection_string(
        conn_str=f"DefaultEndpointsProtocol=https;AccountName={storage_account_name};AccountKey={storage_account_key}",
        share_name="your_share_name",
        directory_path=path,  # Set the path to the nested directory
        file_path=file_name  # Set the name of the file in the nested directory
    ) as file_client:
        with open(local_file_path, "rb") as local_file:
            file_client.upload_file(local_file)
    
    print("File uploaded successfully.")
    
    

    Please let us know if you have any further queries. I’m happy to assist you further.


    Please do not forget to "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.