reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
20.2k stars 1.16k forks source link

rx.download doesn't work with Firefox when using data= with bytes data greater than 30MB #3792

Open jq6l43d1 opened 2 months ago

jq6l43d1 commented 2 months ago

Describe the bug When using rx.download with data= and bytes data that is 30MB or larger the download never happens. It does work in Chrome. When I set the data size to 20MB the download works in Firefox.

To Reproduce

import reflex as rx

import random

class DownloadState(rx.State):

    async def download_random_data(self):
        print("Downloading random data...")
        yield rx.download(
            data=bytes(random.getrandbits(8) for _ in range(30 * 1024 * 1024)),
            filename="random_bytes.bin",
        )

def download_random_data_button():
    return rx.button(
        "Download random bytes",
        on_click=DownloadState.download_random_data,
        size="4"
    )

def index() -> rx.Component:
    return rx.center(
        download_random_data_button(),
        width="100%",
        height="100vh",
    )

app = rx.App()
app.add_page(index)

Expected behavior The download should work as it does in Chrome, or as it does in Firefox when the data is 20MB or less.

Specifics (please complete the following information):

Additional context I can see the data downloading when I look at my system monitor but Firefox never actually saves the file or gives any kind of prompt.

dimritium commented 2 months ago

yeah I checked the code and it is creating a base64 url which is probably hitting the limit supported by firefox. Seems like rx.download implementation can be improved. Do you know what would be the correct way to support large files to be downloaded? I also tried creating an API route and returned FastAPI Response with random bytes (30mb+).. that seemed to work from CLI (using backend url) but not via the download button (added a redirect to backend api url)..

jq6l43d1 commented 2 months ago

I found relevant documentation here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs#length_limitations

It looks like the limit for Firefox is 30 MB. This doesn't seem to be an issue with Reflex. Although maybe we could a size limit info to the docs.

dimritium commented 2 months ago

Yes, correct but shouldn't reflex support large file downloads? FastAPI works correctly for such large files. I was wondering if rx.download implementation could be improved like rather than creating a url for bytes data why not send stream of data. Is there any such guide or protocol to follow to correctly implement the download feature?