Nori
Nori

Reputation: 3002

How to download large file from Cloud Run in Django

I have Django project on Cloud Run. When I download small file from page which has below code.

def download_view(request,pk):
    file_path = f'media/{pk}.mp3'
    name = f'{pk}.mp3'
    with open(file_path, 'rb') as f:
        response = HttpResponse(f.read(), content_type='audio/wav')
    response['Content-Disposition'] = f'attachment; filename={name}'
    return response

It's works fine. However, when I download a file (50MB). I got this picture's error. enter image description here

Cloud run's log is like this. I couldn't find any log of traceback.

2021-05-06 12:00:35.668 JSTGET500606 B66 msChrome 72 https://***/download/mp3/2500762/
2021-05-06 11:49:49.037 JSTGET500606 B61 msChrome 72 https://***/download/mp3/2500645/

I'm not sure. Is this error related with download error.

2021-05-06 16:48:32.570 JSTResponse size was too large. Please consider reducing response size.

I think this is upload file size error. So this is not related with this subject of download error.

When I run Django at local, then download same 50MB file. I can download it. I think this download error related with Cloud run. It's stop after request/response. So I think this error coused by Cloud Run. Which was stoped, when I'm still downloading file.

I don't know how to solve this download error. If you have any solution, please help me!

Upvotes: 3

Views: 3516

Answers (2)

Nori
Nori

Reputation: 3002

Thank you @guillaume blaquiere! I solved download error. I post my code for othres.

def _file_iterator(file, chunk_size=512):
    with open(file, 'rb') as f:
        while True:
            c = f.read(chunk_size)
            if c:
                yield c
            else:
                break

def download_view(request,pk):
    file_path = f'media/{pk}.mp3'
    file_name = f'{pk}.mp3'
    response = StreamingHttpResponse(_file_iterator(file_path))
    response['Content-Type'] = 'audio/mpeg'
    response['Content-Disposition'] = f'attachment;filename="{file_name}"'
    return response

I think StreamingHttpResponse is key point of this problem. It's return big file by chunks. It dose not over Cloud Run's limit.

When I used multipart/form-data for Content-Type, I could download file. But it's couldn't open on smart phone, because It couldn't select application. When I download on PC, it's can't show audio file icon. We should select exact content type.

enter image description here

Upvotes: 2

guillaume blaquiere
guillaume blaquiere

Reputation: 75940

The Cloud Run HTTP request/response size is limited to 32Mb. Use a multipart/form-data to send chunks of your big file and not the whole file directly.

Upvotes: 3

Related Questions