Download zipped json file

Hi all,

I’ve been running in circles through streamlit discussions on saving files and I can’t find a way to download this file format: zipped json file.

File has this structure:


data = {
  "name" : "Test",
  "prop" : 
[
  {
    "a": 1,
    "b": 2
  }
]
}

And within Python, I can save my output with:

import json
import zipfile

def save(file):
  jsonString = json.dumps(data ) # json Data
  with zipfile.ZipFile(file, 'w') as zip:
    zip.writestr("Test.json", jsonString)

Where input file in function is the zipped filename e.g. “File.zip”.

I would appreciate if anyone has input on this!

Thanks,
Rob

Found possible solution. It was a combination of one Streamlit answer and what I was doing in the first place in Python outside streamlit :slight_smile:

Here it is, if anyone ever needs it:

# store my data in zip/json
      with zipfile.ZipFile("file.zip", 'w') as zip:
          zip.writestr("Data.json", jsonString)

# Parse made zip file to streamlit button
      with open("file.zip", "rb") as fp:
          btn = st.download_button(
              label="Download ZIP",
              data=fp,
              file_name="file.zip",
              mime="application/octet-stream"
              )

This works great, but leaves “file.zip” saved on disk wherever the app is hosted - is there a way to have the whole process happen in-memory? It looks like st.download_button cannot directly save a ZipFile object

1 Like

If you find out answer to that - do let me know!

I’m creating small files ~15kb, but indeed - my app reaches over the limit every ~24h and it’s either this, or one other function which creates a lot of plots…Since I placed @cache(ttl…) on the plot function; I would assume that this is causing problems. I didn’t even realize that this leaves disk on the app hosting space :confused:

@rdzudzar @scott-trinkle Here you go! :balloon:

The trick is to create an in-memory buffer with io.BytesIO , write to it using zip.writestr , and use st.download_button() to download this in-memory buffer as a .zip file:

import streamlit as st
import json
import zipfile
import io

jsonString = {"name": "Test", "prop": [{"a": 1, "b": 2}]}

# Create an in-memory buffer to store the zip file
with io.BytesIO() as buffer:
    # Write the zip file to the buffer
    with zipfile.ZipFile(buffer, "w") as zip:
        zip.writestr("Data.json", json.dumps(jsonString))

    buffer.seek(0)

    btn = st.download_button(
        label="Download ZIP",
        data=buffer,  # Download buffer
        file_name="file.zip" 
    )

Best,
Snehan

2 Likes

Thank you!

1 Like

Perfect, thanks!