Spaces:
Runtime error
Runtime error
| import io | |
| import re | |
| import uuid | |
| import base64 | |
| import streamlit as st | |
| from typing import Optional, Union | |
| from streamlit.elements.widgets.button import DownloadButtonDataType | |
| DownloadButtonDataType = Union[DownloadButtonDataType, "pd.DataFrame", "Styler"] | |
| HAS_PD = True | |
| def download_button(label: str, | |
| data: DownloadButtonDataType, | |
| file_name: Optional[str] = None) -> str: | |
| """Generates a link to download the given data, support file-like object and pd.DataFrame. | |
| Params | |
| Args: | |
| label: text show on page. | |
| data: file-like object or pd.DataFrame. | |
| file_name: filename and extension of file. e.g. mydata.csv, | |
| Raises: | |
| RuntimeError: when data type is not supported | |
| Returns: | |
| the anchor tag to download object_to_download | |
| Examples: | |
| download_button('Click to download data!', your_df, 'YOUR_DF.xlsx'), | |
| download_button('Click to download text!', your_str.encode(), 'YOUR_STRING.txt') | |
| """ | |
| # inspired by https://gist.github.com/chad-m/6be98ed6cf1c4f17d09b7f6e5ca2978f | |
| data_as_bytes: bytes | |
| if isinstance(data, str): | |
| data_as_bytes = data.encode() | |
| elif isinstance(data, io.TextIOWrapper): | |
| string_data = data.read() | |
| data_as_bytes = string_data.encode() | |
| # mimetype = mimetype or "text/plain" | |
| # Assume bytes; try methods until we run out. | |
| elif isinstance(data, bytes): | |
| data_as_bytes = data | |
| elif isinstance(data, io.BytesIO): | |
| data.seek(0) | |
| data_as_bytes = data.getvalue() | |
| elif isinstance(data, io.BufferedReader): | |
| data.seek(0) | |
| data_as_bytes = data.read() | |
| elif isinstance(data, io.RawIOBase): | |
| data.seek(0) | |
| data_as_bytes = data.read() or b"" | |
| elif HAS_PD and hasattr(data, "to_excel"): | |
| bio = io.BytesIO() | |
| data.to_excel(bio) | |
| bio.seek(0) | |
| data_as_bytes = bio.read() | |
| else: | |
| raise RuntimeError("Invalid binary data format: %s" % type(data)) | |
| b64 = base64.b64encode(data_as_bytes).decode() | |
| button_uuid = str(uuid.uuid4()).replace("-", "") | |
| button_id = re.sub(r"\d+", "", button_uuid) | |
| custom_css = f""" | |
| <style> | |
| #{button_id} {{ | |
| background-color: rgb(255, 255, 255); | |
| color: rgb(38, 39, 48); | |
| padding: 0.4em 0.6em; | |
| position: relative; | |
| text-decoration: none; | |
| border-radius: 4px; | |
| border-width: 1px; | |
| border-style: solid; | |
| border-color: rgba(49, 51, 63, 0.2); | |
| border-image: initial; | |
| }} | |
| #{button_id}:hover {{ | |
| border-color: rgb(246, 51, 102); | |
| color: rgb(246, 51, 102); | |
| }} | |
| #{button_id}:active {{ | |
| box-shadow: none; | |
| background-color: rgb(246, 51, 102); | |
| color: white; | |
| }} | |
| </style> """ | |
| dl_link = ( | |
| custom_css | |
| + f'<a class="steDownloadButton" download="{file_name}" id="{button_id}" ' | |
| f'href="data:file/txt;base64,{b64}">{label}</a><br></br>' | |
| ) | |
| div_dl_link = f"""<div class="row-widget stDownloadButton">{dl_link}</div>""" | |
| st.markdown(div_dl_link, unsafe_allow_html=True) | |
| return dl_link | |