Retrieval and display from Azure Blob Storage, to Flask Python, to HTML/JS?
Asked Answered
L

2

6

I have a simple Flask Azure-webapp which I would like the user to be able to upload images. The images are then stored in an Azure Blob.

import os, uuid
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

try:
    print("Azure Blob storage v12 - Python quickstart sample")
    # Quick start code goes here
except Exception as ex:
    print('Exception:')
    print(ex)

connect_str = "XXXXX"
blob_service_client = BlobServiceClient.from_connection_string(connect_str)

container_name = 'kdprivatecontainer'
container_client = blob_service_client.get_container_client(container_name)

# List the blobs in the container
print("\nListing blobs...")
blob_list = container_client.list_blobs()
for blob in blob_list:
    print("\t" + blob.name)

I can see the names of the files through this method... how do I pass the images to a front-end webpage while keeping the container as 'private'.

A total stab in the dark is: but obviously doesn't work :/

from flask import Flask, render_template
app = Flask(app)

@app.route("/showimg')
def showimage():
    blobimage = blob[9].url????
    return render_template('showimage.html, img=blobimage)

Any guidance is appreciated. :)

Lowbred answered 28/1, 2020 at 8:0 Comment(0)
S
9

I'm very agree with @GauravMantri's answer, you need to generate an url with sas token for your images as blobs in the private container using the funtion generate_container_sas or generate_blob_sas of Azure Blob Storage SDK v12 for Python.

Just additionally, I think you may need some sample code which can work for you immediately, so I worked for it.

Here is my sample code.

from datetime import datetime, timedelta
from azure.storage.blob import generate_container_sas, ContainerSasPermissions

account_name = "<your account name>"
account_key = "<your account key>"
container_name = "<your container name, such as `test`>"

# using generate_container_sas
def get_img_url_with_container_sas_token(blob_name):
    container_sas_token = generate_container_sas(
        account_name=account_name,
        container_name=container_name,
        account_key=account_key,
        permission=ContainerSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    blob_url_with_container_sas_token = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}?{container_sas_token}"
    return blob_url_with_container_sas_token

from azure.storage.blob import generate_blob_sas, BlobSasPermissions

# using generate_blob_sas
def get_img_url_with_blob_sas_token(blob_name):
    blob_sas_token = generate_blob_sas(
        account_name=account_name,
        container_name=container_name,
        blob_name=blob_name,
        account_key=account_key,
        permission=ContainerSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    blob_url_with_blob_sas_token = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}?{blob_sas_token}"
    return blob_url_with_blob_sas_token

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/showimg")
@app.route("/showimg/<blob_name>")
def hello_world(blob_name=None):
    img_url_with_sas_token = get_img_url_with_blob_sas_token(blob_name)
    # Or 
    # img_url_with_sas_token = get_img_url_with_container_sas_token(blob_name)
    return render_template('showimage.html', img_url_with_sas_token=img_url_with_sas_token)

app.run()

And my templates/showimage.html is very simple as below.

<html>
<head>
</head>
<body>
    <img src="{{img_url_with_sas_token}}" />
</body>
</html>

There is an image named test_cat2.jpg in my test container which I used for testing, so the result as the figure below.

enter image description here

Scrag answered 28/1, 2020 at 18:36 Comment(3)
Yes! Thank you so much, this looks awesome. I will test it out ASAP and mark as correct once I get it working. Really appreciate the help! Life saver. Can I ask, where did you learn how to do this? The online resources I followed were either old or not relating to python/flask?Lowbred
@user6372319 You can refer to the related resources, such as pypi.org/project/azure-storage-blob and the source code github.com/Azure/azure-sdk-for-python/blob/… for sas token, and flask.palletsprojects.com/en/1.1.x/quickstart/… for flask render template topic. Ofcourse, you need to integrate them together by yourself, it's the key and important.Scrag
@PeterPan, this solution works great! Is there a way to rewrite or masquerade the blob URL that it looks like the file has been served from the web server?Dinger
D
1

how do I pass the images to a front-end webpage while keeping the container as 'private'.

Considering the blob container is private, you would need to create a Shared Access Signature (SAS) token with at least Read permission and append that to the blob's URL (to get SAS URL). When you use this SAS URL in the front end, you will be able to show the blob's contents.

You can either create a SAS on a container using generate_container_sas and use that with all blobs or create a unique SAS for each blobs in the list using generate_blob_sas.

Desdamona answered 28/1, 2020 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.