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 MBServing 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.
Testing Flask Appspytest, the test client, app context and covering auth and JSON routes.