Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion reflex/.templates/web/utils/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,19 @@ export const applyEvent = async (event, socket, navigate, params) => {
if (event.name == "_download") {
const a = document.createElement("a");
a.hidden = true;
a.href = event.payload.url;
if (event.payload.url.startsWith("DOWNLOAD_AS_BLOB:")) {
const blob = new Blob(
[event.payload.url.replace("DOWNLOAD_AS_BLOB:", "")],
{ type: "application/octet-stream" },
);
const url = URL.createObjectURL(blob);
a.href = url;
window.setTimeout(function () {
window.URL.revokeObjectURL(url);
}, 60000); // Wait 60 seconds
} else {
a.href = event.payload.url;
}
// Special case when linking to uploaded files
if (a.href.includes("getBackendURL(env.UPLOAD)")) {
a.href = eval?.(
Expand Down
14 changes: 13 additions & 1 deletion reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,13 +1230,17 @@ def download(
url: str | Var | None = None,
filename: str | Var | None = None,
data: str | bytes | Var | None = None,
as_blob: bool | None = None,
mime_type: str | Var | None = None,
) -> EventSpec:
"""Download the file at a given path or with the specified data.

Args:
url: The URL to the file to download.
filename: The name that the file should be saved as after download.
data: The data to download.
as_blob: Downloads the provided `data` via JS `new Blob(...)`.
mime_type: Optional blob mime type when `as_blob` is set to True. Default is `application/octet-stream`.

Raises:
ValueError: If the URL provided is invalid, both URL and data are provided,
Expand All @@ -1258,13 +1262,20 @@ def download(

if filename is None:
filename = ""
if mime_type is None:
mime_type = "application/octet-stream"

if data is not None:
if url is not None:
msg = "Cannot provide both URL and data to download."
raise ValueError(msg)

if isinstance(data, str):
if as_blob:
url = f"DOWNLOAD_AS_BLOB:{data}"
if isinstance(data, Var):
url = f"DOWNLOAD_AS_BLOB:{data.to(str)}"

elif isinstance(data, str):
# Caller provided a plain text string to download.
url = "data:text/plain," + urllib.parse.quote(data)
elif isinstance(data, Var):
Expand Down Expand Up @@ -1293,6 +1304,7 @@ def download(
get_fn_signature(download),
url=url,
filename=filename,
mime_type=mime_type,
)


Expand Down
Loading