Home > Back-end >  How to Download/Upload Files from Azure Blob using Python in Spyder/Anaconda
How to Download/Upload Files from Azure Blob using Python in Spyder/Anaconda

Time:02-14

I am new to Azure. I created a Blob Storage today. I am trying to run some Python code that I found online, to download files fro this Blob Container. Here is the code that I am testing.

# download_blobs.py
# Python program to bulk download blob files from azure storage
# Uses latest python SDK() for Azure blob storage
# Requires python 3.6 or above
import os
from azure.storage.blob import BlobServiceClient, BlobClient
from azure.storage.blob import ContentSettings, ContainerClient
 
# IMPORTANT: Replace connection string with your storage account connection string
# Usually starts with DefaultEndpointsProtocol=https;...
MY_CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName=ryanpythonstorage;AccountKey=my_account_key;EndpointSuffix=core.windows.net"

# Replace with blob container
MY_BLOB_CONTAINER = "ryanpythonstorage" #copied from Access Keys
 
# Replace with the local folder where you want files to be downloaded
LOCAL_BLOB_PATH = "C:\\Users\\ryans\\Desktop\\blob\\"
 
class AzureBlobFileDownloader:
  def __init__(self):
    print("Intializing AzureBlobFileDownloader")
 
    # Initialize the connection to Azure storage account
    self.blob_service_client =  BlobServiceClient.from_connection_string(MY_CONNECTION_STRING)
    self.my_container = self.blob_service_client.get_container_client(MY_BLOB_CONTAINER)
 
 
  def save_blob(self,file_name,file_content):
    # Get full path to the file
    download_file_path = os.path.join(LOCAL_BLOB_PATH, file_name)
 
    # for nested blobs, create local path as well!
    os.makedirs(os.path.dirname(download_file_path), exist_ok=True)
 
    with open(download_file_path, "wb") as file:
      file.write(file_content)
 
  def download_all_blobs_in_container(self):
    my_blobs = self.my_container.list_blobs()
    for blob in my_blobs:
      print(blob.name)
      bytes = self.my_container.get_blob_client(blob).download_blob().readall()
      self.save_blob(blob.name, bytes)
 
# Initialize class and upload files
azure_blob_file_downloader = AzureBlobFileDownloader()
azure_blob_file_downloader.download_all_blobs_in_container()

Here is the result that I see when I run the code.

Intializing AzureBlobFileDownloader
Traceback (most recent call last):

  File "C:\Users\ryans\AppData\Local\Temp\ipykernel_14020\3010845424.py", line 37, in <module>
    azure_blob_file_downloader.download_all_blobs_in_container()

  File "C:\Users\ryans\AppData\Local\Temp\ipykernel_14020\3010845424.py", line 30, in download_all_blobs_in_container
    for blob in my_blobs:

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\core\paging.py", line 129, in __next__
    return next(self._page_iterator)

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\core\paging.py", line 76, in __next__
    self._response = self._get_next(self.continuation_token)

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\storage\blob\_list_blobs_helper.py", line 79, in _get_next_cb
    process_storage_error(error)

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\storage\blob\_shared\response_handlers.py", line 177, in process_storage_error
    exec("raise error from None")   # pylint: disable=exec-used # nosec

  File "<string>", line 1, in <module>

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\storage\blob\_list_blobs_helper.py", line 72, in _get_next_cb
    return self._command(

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\storage\blob\_generated\operations\_container_operations.py", line 1479, in list_blob_flat_segment
    map_error(status_code=response.status_code, response=response, error_map=error_map)

  File "C:\Users\ryans\anaconda3\lib\site-packages\azure\core\exceptions.py", line 105, in map_error
    raise error

ResourceNotFoundError: The specified container does not exist.
RequestId:4d2df1c1-a01e-008b-4209-21e493000000
Time:2022-02-13T18:44:14.1140999Z
ErrorCode:ContainerNotFound
Content: <?xml version="1.0" encoding="utf-8"?><Error><Code>ContainerNotFound</Code><Message>The specified container does not exist.
RequestId:4d2df1c1-a01e-008b-4209-21e493000000
Time:2022-02-13T18:44:14.1140999Z</Message></Error>

Ultimately, I want to be able to do two things:

  1. download files from my Blob to my local machine
  2. upload files from my local machine to my Blob.

CodePudding user response:

The error message is that it cannot find the container. It could be:

  • A problem with rights (connection string)
  • A problem with the container name

In MY_CONNECTION_STRING and MY_BLOB_CONTAINER the name of your account and the name of your container is the same. If one of these is incorrect it would explain the error.

CodePudding user response:

Here is my final working code.

import os
import uuid
import sys
from azure.storage.blob import BlockBlobService, PublicAccess

try:
    # Create the BlockBlobService that is used to call the Blob service for the storage account
    blob_service_client = BlockBlobService(account_name='your_account_name_goes_here', account_key='your_account_key_goes_here')
    
    # Create a container called 'quickstartblobs'.
    container_name = 'your_container_name_goes_here'
    blob_service_client.create_container(container_name)
    
    # Set the permission so the blobs are public.
    blob_service_client.set_container_acl(container_name, public_access=PublicAccess.Container)
    
    # Create Sample folder if it not exists, and create a file in folder Sample to test the upload and download.
    local_path = os.path.expanduser('C:\\Users\\ryans\\Desktop\\blob\\')
        
    local_file_name  = 'charges.csv'
    #local_file_name = "QuickStart_"   str(uuid.uuid4())   ".txt"
    full_path_to_file = os.path.join(local_path, local_file_name)

    print("Temp file = "   full_path_to_file)
    print("\nUploading to Blob storage as blob"   local_file_name)
    
    # Upload the created file, use local_file_name for the blob name
    blob_service_client.create_blob_from_path(container_name, local_file_name, full_path_to_file)
    
    # List the blobs in the container
    print("\nList blobs in the container")
    generator = blob_service_client.list_blobs(container_name)
    
    for blob in generator:
        print("\t Blob name: "   blob.name)

except Exception as e:
    print(e)
    
##############################################################################################


import os
import uuid
import sys
from azure.storage.blob import BlockBlobService, PublicAccess

try:
    
    local_path = os.path.expanduser('C:\\Users\\ryans\\Desktop\\blob\\')
    container_name = 'your_container_name_goes_here'
    local_file_name  = 'charges.csv'
    
    # Download the blob(s).
    # Add '_DOWNLOADED' as prefix to '.txt' so you can see both files in Documents.
    full_path_to_file = os.path.join(local_path, local_file_name)
    print("\nDownloading blob to "   full_path_to_file)
    blob_service_client.get_blob_to_path(container_name, local_file_name, full_path_to_file)
    
    #sys.stdout.write("Sample finished running. When you hit <any key>, the sample will be deleted and the sample application will exit.")
    sys.stdout.flush()
    input()

except Exception as e:
    print(e)

This link was a great resource for me.

https://github.com/Azure-Samples/azure-sdk-for-python-storage-blob-upload-download/blob/master/example.py

  • Related