Learn / Frameworks / Flask / File Uploads and Static Media

Flask · Lesson 9 of 15

File Uploads and Static Media

Accept files safely, store them outside the code tree and serve them in development.

  • Intermediate
  • 14 min read
  • 3 objectives

Before this lessonLesson 8: Error Handlers and Logging

What you will learn

  • Save an upload
  • Reject bad types
  • Serve media locally

Your Progress

0 of 15 lessons 0%

  • Lessons0 / 15
  • Completed0
  • Est. time left~ 4 hours

Create a free account to keep your progress on every device.

Uploads are a common source of bugs and vulnerabilities. Cap size, allow-list extensions, and store files outside the repo with random names.

Saving a file

import uuid
from pathlib import Path
from werkzeug.utils import secure_filename

ALLOWED = {".png", ".jpg", ".jpeg", ".pdf"}
MEDIA = Path(app.config["MEDIA_ROOT"])

@app.route("/upload", methods=["POST"])
def upload():
    f = request.files.get("file")
    if not f or not f.filename:
        abort(400)
    ext = Path(f.filename).suffix.lower()
    if ext not in ALLOWED:
        abort(415)
    name = f"{uuid.uuid4().hex}{ext}"
    dest = MEDIA / name
    f.save(dest)
    return {"id": name}
app.config["MAX_CONTENT_LENGTH"] = 5 * 1024 * 1024   # 5 MB

Serving in development

from flask import send_from_directory

@app.route("/media/<name>")
def media(name):
    return send_from_directory(app.config["MEDIA_ROOT"], name)

In production, put media on object storage (S3) and serve via a CDN. App servers should be stateless.

Up next · Lesson 10Testing Flask Appspytest, the test client, app context and covering auth and JSON routes.