I want to send a file to a user, however the file is generated asynchronously via a thread which can take a long time (even 30 seconds).
I would like the browser to show the file being downloaded right away (with 0 bytes and unknown size), tried via cUrl and it works but with a browser (Chrome or Firefox) this doesn’t happen, the download only starts after the first bytes have been sent.
The only way I’ve been able to find is to send empty characters (u200B) while waiting for the file to be generated (as suggested in this similar problem Chrome doesn’t show file as being downloaded until 8 bytes are sent (Firefox does)), but this way the resulting file contains these characters at the beginning, which then gives problems when loading on other systems.
This is an example of the code (simulating asynchronous creation of the file)
async def async_read_file():
# this code simulate the activate waiting for the file to be created
count = 0
while count < 5:
await asyncio.sleep(2)
count += 1
file = open('file.zip', 'rb')
while True:
data = file.read(64 * 1024)
if not data:
break
yield data
@app.get('/download')
async def download():
async def iterate_file_():
async for chunk in async_read_file():
yield chunk
response = StreamingResponse(iterate_file_(), headers={
"Content-Disposition": "attachment; filename*=utf-8''{}".format(quote('file.zip'))})
return response
Sto usando FastAPI in versione 0.109.2.
C’è un modo di ottenere questo comportamento?
Valerio De Blasio is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.