Right now downloads are managed manually, fetching a file from the backend.
If the file is too big, we stream the response in chunks to optimize the response
(returning the file in chunks means we are not loading the whole thing on memory,
just the chunk we need on that iteration which is 1MB).
Apparently, if we create an anchor element with an href that directly fetches
an endpoint, the download is delegated to the browser instead of the JS code.
By doing this, we can really download as a stream of bytes instead of having to wait
for the whole file to be retrieved from the server.
To do this, we need to generate a temporary URL that points to the file we want to download.
JWT (JSON Web Token) is perfect for this, as we can set the expiration date of the
token so we are not exposing anything longer than what we need.
@app.get("/download/{token}")
async def download():
...
const url = await fetch(`/download/${token}`).then(r => r.text());
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
a.remove();
Useful links:
Right now downloads are managed manually, fetching a file from the backend.
If the file is too big, we stream the response in chunks to optimize the response
(returning the file in chunks means we are not loading the whole thing on memory,
just the chunk we need on that iteration which is 1MB).
Apparently, if we create an
anchorelement with anhrefthat directly fetchesan endpoint, the download is delegated to the browser instead of the JS code.
By doing this, we can really download as a stream of bytes instead of having to wait
for the whole file to be retrieved from the server.
To do this, we need to generate a temporary URL that points to the file we want to download.
JWT (JSON Web Token) is perfect for this, as we can set the expiration date of the
token so we are not exposing anything longer than what we need.
Useful links: