How to zip all the files under azure storage file share and send the zip as response?

109 views Asked by At

I am trying to make a route in flask which zips all the files under file share home directory and sends the zip as response. The code I have has some issue but I am not sure what is wrong here. The response is received by reactJS to download the zip.

@files_blueprint.route('/download/all', methods=['GET'])
def download_all():
    print("-------------downloading all files-----------")
    parent_dir = ShareDirectoryClient.from_connection_string(conn_str=connection_string, share_name=my_share, directory_path="")

    my_list = list(parent_dir.list_directories_and_files())
    print(my_list[0])

    # Get a reference to the file share
    share_client = service.get_share_client(file_share_name)

    # Create a temporary directory to store the zip file
    temp_dir = '/tmp'
    os.makedirs(temp_dir, exist_ok=True)

    # Create a zip archive containing all the files from the root directory of the share
    zip_filename = 'zipped_share.zip'
    with ZipFile(os.path.join(temp_dir, zip_filename), 'w') as zipf:
        for file in share_client.get_directory_client('').list_directories_and_files():
            file_name = file.name
            file_path = os.path.join(temp_dir, file_name)
            file_client = share_client.get_file_client(file_name)
            with open(file_path, 'wb') as local_file:
                file_client.download_file().readinto(local_file)
            zipf.write(file_path, file_name)

    # Send the zip file as a response
    response = send_file(os.path.join(temp_dir, zip_filename), as_attachment=True)

    # Clean up the temporary directory and files
    shutil.rmtree(temp_dir)

    return response

1

There are 1 answers

0
Venkatesan On BEST ANSWER

How to zip all the files under Azure storage file share and send the zip as a response?

You can use the below Python code to route in Flask the list of files & download them as a zip folder and send them reactJS application.

Code:

from flask import Flask, send_file
import os
from zipfile import ZipFile
import shutil
from azure.storage.fileshare import ShareDirectoryClient
from flask_cors import CORS 

app = Flask(__name__)


connection_string = "xxxx"
my_share = "xxxxx"

CORS(app, resources={r"/download/all": {"origins": "http://localhost:3000"}}) 

@app.route('/download/all', methods=['GET'])
def download_all():
    try:
        
        temp_dir = '/tmp'
        os.makedirs(temp_dir, exist_ok=True)

        
        share_directory = ShareDirectoryClient.from_connection_string(connection_string, my_share, directory_path="")

        zip_filename = 'zipped_share.zip'
        with ZipFile(os.path.join(temp_dir, zip_filename), 'w') as zipf:
            for file in share_directory.list_directories_and_files():
                file_name = file.name
                file_path = os.path.join(temp_dir, file_name)
                file_client = share_directory.get_file_client(file_name)
                with open(file_path, 'wb') as local_file:
                    file_client.download_file().readinto(local_file)
                zipf.write(file_path, file_name)

        
        response = send_file(os.path.join(temp_dir, zip_filename), as_attachment=True)

        shutil.rmtree(temp_dir, ignore_errors=True)

        return response

    except Exception as e:
        return str(e), 500

if __name__ == '__main__':
     app.run(host='0.0.0.0', port=5000)

The above code downloads the list of files from Azure file share saves it as a zip sends it to the react app and deletes the temporary path.

In react app under the src folder the App.js is like

App.js

import React from 'react';

function App() {
  const downloadFiles = () => {
    
    fetch('http://127.0.0.1:5000/download/all')  // Replace with the actual Flask app URL
      .then(response => {
        // Check if the response is successful (status code 200)
        if (response.status === 200) {
          // Convert the response to a blob
          return response.blob();
        } else {
          throw new Error('Failed to download files');
        }
      })
      .then(blob => {
        // Create a URL for the blob
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'zipped_share.zip';  // The desired file name
        a.click();
        window.URL.revokeObjectURL(url);
      })
      .catch(error => {
        console.error(error);
      });
  };

  return (
    <div>
      <h1>Download All Files</h1>
      <button onClick={downloadFiles}>Download All Files</button>
    </div>
  );
}

export default App;

My flask app output:

enter image description here

Front end output: enter image description here

Atlast in browser:

enter image description here