How to download an Azure Blob Storage file via URL in Python?

10,251

Solution 1

For downloading using url directly, you should put the blob in a public container, or in the private container then you should generate a sas token for the blob(the url looks like : https://xxx.blob.core.windows.net/aa1/0116.txt?sp=r&st=2019-06-26T09:47:04Z&se=2019-06-26xxxxx).

I test your code with the url which contains a sas token, it can be downloaded.

Test result:

enter image description here

How to generate sas token for a blob:

enter image description here

Solution 2

As on Dec 26, 2019 I am unable to import BaseBlobService from azure cloud storage. Neither of BlobPermissions, generate_blob_shared_access_signature worked for me. Below is something I used and it worked in my case and hope it helps

from azure.storage.blob import generate_blob_sas, AccountSasPermissions

def scan_product():

    account_name=<account_name>
    container_name=<container_name>
    blob_name=<blob_name>
    account_key=<account_key>
    url = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}"
    sas_token = generate_blob_sas(
        account_name=account_name,
        account_key=account_key,
        container_name=container_name,
        blob_name=blob_name,
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )

    url_with_sas = f"{url}?{sas_token}"

Solution 3

Actually, you can generate a blob url with sas token in Azure Storage SDK for Python for accessing directly, as my sample code below.

from azure.storage.blob.baseblobservice import BaseBlobService
from azure.storage.blob import BlobPermissions
from datetime import datetime, timedelta

account_name = '<account name>'
account_key = '<account key>'
container_name = '<container name>'
blob_name = '<blob name>'

url = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}"

service = BaseBlobService(account_name=account_name, account_key=account_key)
token = service.generate_blob_shared_access_signature(container_name, blob_name, permission=BlobPermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1),)

url_with_sas = f"{url}?{token}"

Then,

import urllib
import numpy as np

req = urllib.urlopen(url_with_sas)
img = np.asarray(bytearray(req.read()), dtype=np.uint8)

Solution 4

To solve the issue all I needed to do was to change the Blob Storage access level to Blob (anonymous read access for blob only). Once this is done, it will work.

enter image description here

Share:
10,251

Related videos on Youtube

Marisa
Author by

Marisa

Updated on June 04, 2022

Comments

  • Marisa
    Marisa almost 2 years

    I am trying to download an Azure Blob Storage file from my storage account, to do so, I have checked what the URL is and I am doing the following:

    with urllib.request.urlopen("<url_file>") as resp:
        img = np.asarray(bytearray(resp.read()), dtype="uint8")
    

    But I am getting the following error:

    urllib.error.HTTPError: HTTP Error 404: The specified resource does not exist.
    

    I have doubled checked that the url is correct. Could this have something to do with not having passed the keys of my subscription or any other info about the Storage Account?

    Any idea?

  • Ivan Yang
    Ivan Yang almost 5 years
    Hi, I also mentioned that make the container public in my answer. You should consider my post. Thanks.
  • Siddharth Pant
    Siddharth Pant almost 4 years
    You sir are a godsend! (btw if you are on jupyter notebook and trying to print the url_with_sas, it will URL encode it so beware of that). I got the URL thingy but then was stuck for an hour on that jupyter URL encode behaviour.
  • S Andrew
    S Andrew almost 3 years
    Bhai dil jeet liya