python 44 lines · 8 steps

Handling secure file uploads in Flask

A Flask blueprint that validates, renames, and stores uploaded files while rejecting bad or oversized requests.

Explained by highlit
1import os
2import uuid
3 
4from flask import Blueprint, current_app, jsonify, request
5from werkzeug.exceptions import RequestEntityTooLarge
6from werkzeug.utils import secure_filename
7 
8uploads = Blueprint("uploads", __name__)
9 
10ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "pdf"}
11MAX_CONTENT_LENGTH = 8 * 1024 * 1024
12 
13 
14def _is_allowed(filename):
15 _, _, ext = filename.rpartition(".")
16 return "." in filename and ext.lower() in ALLOWED_EXTENSIONS
17 
18 
19@uploads.route("/documents", methods=["POST"])
20def upload_document():
21 if "file" not in request.files:
22 return jsonify(error="no file part in request"), 400
23 
24 upload = request.files["file"]
25 if not upload.filename:
26 return jsonify(error="no file selected"), 400
27 
28 if not _is_allowed(upload.filename):
29 return jsonify(error="unsupported file type"), 415
30 
31 safe_name = secure_filename(upload.filename)
32 stored_name = f"{uuid.uuid4().hex}_{safe_name}"
33 dest = os.path.join(current_app.config["UPLOAD_DIR"], stored_name)
34 
35 upload.save(dest)
36 size = os.path.getsize(dest)
37 
38 return jsonify(filename=stored_name, original=safe_name, size=size), 201
39 
40 
41@uploads.errorhandler(RequestEntityTooLarge)
42def handle_too_large(err):
43 limit_mb = MAX_CONTENT_LENGTH // (1024 * 1024)
44 return jsonify(error=f"file exceeds {limit_mb}MB limit"), 413
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Validate presence, filename, and type before touching the filesystem to fail fast with meaningful status codes.
  2. 2Sanitize and randomize stored filenames to avoid path traversal and name collisions.
  3. 3Register an error handler so framework-level exceptions like oversized bodies return clean JSON.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Handling secure file uploads in Flask — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code