Sometimes you have a need to receive or send large files in chunks. To do this properly you don’t want to hold the whole file in memory or save it to disk. Ideally, you would use a stream that processes that file in chunks as it’s being read or written. I had this need at work and it was hard to find good examples of this done in Python with Flask - since that’s what our machine learning (ML) applications use. I’ve put a small example in this repo.
How It Works
Flask’s request has a stream, that will have the file data you are uploading. You can read from it treating it as a file-like object. The trick seems to be that you shouldn’t use other request attributes like request.form or request.file because this will materialize the stream into memory/file. Flask by default saves files to disk if they exceed 500Kb, so don’t touch file.
Example
You can follow the README to try out the project. I’m posting the same code here for convenience. There are 3 scenarios covered:
Upload file to disk
Download from a URL, could be replaced with a file instead of URL
Proxy - pipe it from a client to this server and to another server
Other Options
I’m more of a Scala guy rather than Python, so I couldn’t stop myself from posting an example of Scala multipart file upload using Spray/Akka-HTTP:
Here the uploaded file being processed asynchronously as a stream of chunks of bytes. It supports multiple file uploads, i.e. curl -F "file=@file1.pdf" -F "file=@file2.doc" http://localhost/convert.
Reactive Streams and Flows for the win!