Handle MultipleUpload file uploads with Flask using
request.files for multipart parsing.
This guide covers both standard uploads and chunked uploads with resume support.
pip install flask flask-cors
Use Flask's built-in request object to receive multipart/form-data uploads. Files are saved to disk with a unique GUID filename.
import os
import uuid
import shutil
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app, expose_headers=[
"Content-Type", "X-Upload-Id", "X-Chunk-Index",
"X-Chunk-Count", "X-File-Name", "X-File-Size"
])
UPLOAD_DIR = os.path.join(os.path.dirname(__file__), "uploads")
CHUNK_DIR = os.path.join(UPLOAD_DIR, "chunks")
os.makedirs(UPLOAD_DIR, exist_ok=True)
app.config["MAX_CONTENT_LENGTH"] = 200 * 1024 * 1024 # 200 MB
@app.route("/upload", methods=["POST"])
def upload():
if "file" not in request.files:
return jsonify(success=False, error="No file uploaded"), 400
file = request.files["file"]
file_guid = str(uuid.uuid4())
ext = os.path.splitext(file.filename)[1] if file.filename else ""
dest_path = os.path.join(UPLOAD_DIR, file_guid + ext)
file.save(dest_path)
file_size = os.path.getsize(dest_path)
return jsonify(
success=True,
fileGuid=file_guid,
fileName=file.filename,
fileSize=file_size
)
Each chunk arrives as a raw body with custom headers. Store chunks in a temporary directory and assemble the final file once all chunks have arrived.
@app.route("/upload-chunk", methods=["POST"])
def upload_chunk():
upload_id = request.headers.get("X-Upload-Id")
chunk_index = int(request.headers.get("X-Chunk-Index", 0))
chunk_count = int(request.headers.get("X-Chunk-Count", 0))
file_name = request.headers.get("X-File-Name", "unknown")
file_size = int(request.headers.get("X-File-Size", 0))
if not upload_id or not chunk_count:
return jsonify(success=False, error="Missing chunk headers"), 400
session_dir = os.path.join(CHUNK_DIR, upload_id)
os.makedirs(session_dir, exist_ok=True)
# Save this chunk
chunk_path = os.path.join(session_dir, f"chunk_{chunk_index}")
with open(chunk_path, "wb") as f:
f.write(request.get_data())
# Count received chunks
received = len([
name for name in os.listdir(session_dir)
if name.startswith("chunk_")
])
if received == chunk_count:
# Assemble final file
file_guid = str(uuid.uuid4())
ext = os.path.splitext(file_name)[1] if file_name else ""
final_path = os.path.join(UPLOAD_DIR, file_guid + ext)
with open(final_path, "wb") as output:
for i in range(chunk_count):
cp = os.path.join(session_dir, f"chunk_{i}")
with open(cp, "rb") as chunk_file:
output.write(chunk_file.read())
# Clean up chunks
shutil.rmtree(session_dir)
return jsonify(
success=True,
fileGuid=file_guid,
fileName=file_name,
fileSize=file_size
)
return jsonify(success=True, chunksReceived=received)
if __name__ == "__main__":
app.run(port=5000, debug=True)
Both endpoints must return this JSON structure on successful upload completion.
{
"success": true,
"fileGuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"fileName": "photo.jpg",
"fileSize": 204800
}
Initialize MultipleUpload on the client, pointing to your Flask endpoints.
<link rel="stylesheet" href="multipleupload.css" />
<div id="uploader"></div>
<script src="multipleupload.js"></script>
<script>
var uploader = new MultipleUpload("#uploader", {
uploadUrl: "http://localhost:5000/upload",
chunkUploadUrl: "http://localhost:5000/upload-chunk",
chunkSize: 2 * 1024 * 1024, // 2 MB chunks
onFileUploaded: function (file, response) {
console.log("Uploaded:", response.fileName, response.fileGuid);
}
});
</script>