Issue
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
Solution
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:
Front end output:
Atlast in browser:
Answered By - Venkatesan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.