2

I'm just wondering is there a way to extract a password protected zip file from Azure Storage. I tried using a python Azure Function to no avail but had a problem reading the location of the file.

Would the file have to stored on a shared location temporarily in order to achieve?

Just looking for a bit of direction here am I missing a step maybe?

Regards, James

1 Answers1

2

Azure blob storage provides storing functionality only, there is no running env to perform unzip operation. So basically, we should download .zip file to Azure function, unzip it and upload files in .zip file 1 by 1.

For a quick test, I write an HTTP trigger Azure function demo that unzipping a zip file with password-protected, it works for me on local :

import azure.functions as func
import uuid
import os
import shutil
from azure.storage.blob import ContainerClient
from zipfile import ZipFile

storageAccountConnstr = '<storage account conn str>'
container = '<container name>'

#define local temp path, on Azure, the path is recommanded under /home 
tempPathRoot = 'd:/temp/'
unZipTempPathRoot = 'd:/unZipTemp/'


def main(req=func.HttpRequest) -> func.HttpResponse:
    reqBody = req.get_json()
    fileName = reqBody['fileName']
    zipPass =  reqBody['password']

    container_client = ContainerClient.from_connection_string(storageAccountConnstr,container)

    #download zip file 
    zipFilePath = tempPathRoot + fileName
    with open(zipFilePath, "wb") as my_blob:
       download_stream = container_client.get_blob_client(fileName).download_blob()
       my_blob.write(download_stream.readall())

    #unzip to temp folder
    unZipTempPath = unZipTempPathRoot + str(uuid.uuid4())
    with ZipFile(zipFilePath) as zf:
        zf.extractall(path=unZipTempPath,pwd=bytes(zipPass,'utf8'))

    #upload all files in temp folder
    for root, dirs, files in os.walk(unZipTempPath):
        for file in files: 
            filePath = os.path.join(root, file)
            destBlobClient = container_client.get_blob_client(fileName + filePath.replace(unZipTempPath,''))
            with open(filePath, "rb") as data:
                destBlobClient.upload_blob(data,overwrite=True)
    
    #remove all temp files 
    shutil.rmtree(unZipTempPath)
    os.remove(zipFilePath)

    return func.HttpResponse("done")

Files in my container: enter image description here

Result: enter image description here enter image description here enter image description here

Using blob triggers will be better to do this as it will cause time-out errors if the size of your zip file is huge.

Anyway, this is only a demo that shows you how to do this.

Stanley Gong
  • 11,522
  • 1
  • 8
  • 16
  • Thanks very much!! Saved me weeks of headache...Quick one. Will the temporary file location work once deployed to Azure? – user14780013 Dec 14 '20 at 17:09
  • @user14780013, glad to know it is helpful. temp path is a common file path on Azure, it always works. Zip files will be removed after use. – Stanley Gong Dec 15 '20 at 01:25
  • @user14780013 BTW, you should create temp path first if they not exist on Azure – Stanley Gong Dec 15 '20 at 02:21
  • Still having the same problem as before, "No such file or directory" on the open function.? Code is almost identical to the above, besides the paths "d:/home/temp/test.zip". Created two folders under /home/ identical to the above? – user14780013 Dec 15 '20 at 16:54
  • on Azure function, you should create this 2 path manually by command, such as : mkdir /home/temp , and change the path in code above – Stanley Gong Dec 16 '20 at 01:34
  • @StanleyGong - is it possible to unzip password protected file on Azure blob itself (without download and upload)? please refer my question here - https://stackoverflow.com/questions/65612148/azure-function-unzip-password-protected-file-using-python-code – Rameshwar Pawale Jan 07 '21 at 14:39