1

HTML newbie here

I am working on an app using Streamlit. Based on the user inputs to the fields available, I am generating some data which I want to download in the form of a .txt file.

The data that I want to download is generated when I do

to_save = abc.serialize().encode("ascii", "ignore")

and when I do print(to_save), I get (this is just a small part of a very huge text data)

b"UNA:+.? 'UNB+UNOC:3+9978715000006:14+9978715000006:14+200529:1139+50582307060_WP?+_200101_200201++TL'UNH+1+MSCONS:D:04B:UN:2.3'BGM+7+50582307060_WP?+_200101_200201-1+9'DTM+137:202005291139:203'RFF+Z13:13008'NAD+MS+9978715000006::9'CTA+IC+:Michael Jordan'COM+m.jordan@energycortex.com:EM'NAD+MR+9978715000006::9'"

Now, I want to save this information as a .txt file via an HTML link. I am following:

  1. How to download a file in Streamlit
  2. How to force fully download txt file on link?

and I have

reference = 50582307060_WP+_200101_200201
to_save = abc.serialize().encode("ascii", "ignore")
href = f'<a href="data:text/plain;charset=UTF-8,{to_save}" download={reference}.txt>Download File</a> (right-click and save as {reference}.txt)'
st.markdown(href, unsafe_allow_html=True)

But this doesn't work and shows as follows:

The start

enter image description here

The end

enter image description here

and when I do:

to_save = abc.serialize().encode("ascii", "ignore")
href = f'<a href="data:text/plain;charset=UTF-8" download={reference}.txt>Download File</a> (right-click and save as {reference}.txt)'
st.markdown(href, unsafe_allow_html=True)

I get

enter image description here

The problem with this being that the information that has to be saved as a .txt file (to_save = abc.serialize().encode("ascii", "ignore")) isn't being saved and I get a Failed-Network error

What is the mistake that I am doing and how can I enable saving the information stored in to_save (to_save = abc.serialize().encode("ascii", "ignore")) as an HTML downloadable link? Also, the file should be saved as 'reference.txt', with reference being defined as a variable above.

some_programmer
  • 3,268
  • 4
  • 24
  • 59

1 Answers1

3

I reckon I have found a solution to your problem. Though I can't be entirely sure, it has two causes. The first one lies in the href attribute of the download link. The problem here is the " (double quotes) in the to_save variables data. The html, for what I could test with the by you provided data, renders it as follows:

<a href="data:text/plain;charset=UTF-8,b"UNA:+.? 'UNB+UNOC:3+9978715000006:14+9978715000006:14+200529:1139+50582307060_WP?+_200101_200201++TL'UNH+1+MSCONS:D:04B:UN:2.3'BGM+7+50582307060_WP?+_200101_200201-1+9'DTM+137:202005291139:203'RFF+Z13:13008'NAD+MS+9978715000006::9'CTA+IC+:Michael Jordan'COM+m.jordan@energycortex.com:EM'NAD+MR+9978715000006::9'"" download=filename.txt>Download File</a>

As you can see the value of the href attribute isn't all in the blue color (here in the stackoverflow code container above). That is because of the " that interrupt the string, it closes the earlier opened " after href=". In order to prevent this behaviour, you should replace the " in to_save with &quot;. To the user this will look the same as " but the browser will treat it like a normal string.

You should add the following line of code to your python script to make that happen

to_save = abc.serialize().encode("ascii", "ignore")
#add this line:
to_save = to_save.replace('"','&quot;')

Next the download attribute doesn't have any double quotes around it's value. It should, formally, look like this: download="filename.txt". Then again, for safety replace any possible"with"`.

The full python code should now look like this:

reference = 50582307060_WP+_200101_200201
reference = reference.replace('"','&quot;')

to_save = abc.serialize().encode("ascii", "ignore")
to_save = to_save.replace('"','&quot;')

href = f'<a href="data:text/plain;charset=UTF-8,{to_save}" download="{reference}.txt">Download File</a> (right-click and save as {reference}.txt)'
st.markdown(href, unsafe_allow_html=True)

Hope this helps! If not, please comment.

Chiel
  • 1,324
  • 1
  • 11
  • 30