How to download local folder?

Hi community!

Can I download a local folder in streamlit app?

I make a AI images style transfer app on streamlit

I put results(processed images) in A folder

and I wanna compress the processed images to rar or zip file and let user can download it

how can I do?

2 Likes

Hi @sevaroy,

You could try to zip the folder programmatically then expose it through a download link :slight_smile:.

Donโ€™t hesitate to come back with your code snippet if you have trouble implementing !

Fanilo

2 Likes

@sevaroy: this post seems related, and thereโ€™s a suggestion on how to do this :slight_smile:

1 Like
 def zipdir(path, ziph):
                 # ziph is zipfile handle
                for root, dirs, files in os.walk(png_path):
                    for file in files:
                        ziph.write(os.path.join(root, file))
            zip_path = 'Python.zip'        
            zipf = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
            zipdir('tmp/', zipf)
            zipf.close()

            with open(zip_path, "rb") as f:
                bytes = f.read()
                b64 = base64.b64encode(bytes).decode()
                href = f'<a href="data:file/csv;base64,{b64}">Download File</a> (right-click and save as &lt;some_name&gt;.csv)'

                st.sidebar.markdown(href, unsafe_allow_html=True)

Hi community!

now I can compress A folder , it work

but the download link not working

thanks for help

2 Likes

would be interested to know myself. I could not get a download link working for something that was not an excel/text file. In my case I have a binary (midi) file and in both our cases this part

 b64 = base64.b64encode(bytes).decode()
href = f'<a href="data:file/csv;base64,{b64}"> .... etc etc

is not right for what we want.

with open(zip_path, โ€œrbโ€) as f:

    bytes = f.read()
    b64 = base64.b64encode(bytes).decode()
    href = f'<a href="data:file/zip;base64,{b64}" download=\'{filename}.zip\'>\
        Click to download\
    </a>'
st.sidebar.markdown(href, unsafe_allow_html=True)

Hi community

now it all work!

I figure out the data type and fix it.

thanks for help

3 Likes

There is a good example in the download button offered as a work around. See:
The download_button() function is an extension of a workaround based on
the discussions covered in more detail at Awesome Streamlit.
Go to Gallery โ†’ Select the App Dropdown โ†’ Choose โ€œFile Download Workaroundโ€
for more information.

When you use the code offered there. Check the last example to get this code:

--------------------------

# Select a file to download
# --------------------------
if st.checkbox('Select a file to download'):
    st.write('~> Use if you want to test uploading / downloading a certain file.')

    # Upload file for testing
    folder_path = st.text_input('Enter directory: deafult .', '.')
    filename = file_selector(folder_path=folder_path)

    # Load selected file
    with open(filename, 'rb') as f:
        s = f.read()

    download_button_str = download_button(s, filename, f'Click here to download {filename}')
    st.markdown(download_button_str, unsafe_allow_html=True)

to sum up, a python code snippet

import base64
import shutil

def create_download_zip(zip_directory, zip_path, filename='foo.zip"):
    """ 
        zip_directory (str): path to directory  you want to zip 
        zip_path (str): where you want to save zip file
        filename (str): download filename for user who download this
    """
    shutil.make_archive(zip_path, 'zip', zip_directory)
    with open(zip_path, 'rb') as f:
        bytes = f.read()
        b64 = base64.b64encode(bytes).decode()
        href = f'<a href="data:file/zip;base64,{b64}" download=\'{filename}\'>\
            download file \
        </a>'
        st.markdown(href, unsafe_allow_html=True)