Python FastAPI Tutorial (Part 12): File Uploads - Image Processing, Validation, and Storage

| Programming | February 27, 2026 | 6.63 Thousand views | 34:31

TL;DR

Corey Schafer demonstrates implementing secure profile picture uploads in FastAPI using Pillow for image resizing and format standardization, with proper handling of CPU-bound tasks in async contexts and safe file transaction patterns to prevent data loss.

🖼️ Image Processing Setup 3 insights

Process images with Pillow

Resize uploads to 300x300 pixels using LANCZOS resampling, convert to RGB format to handle transparency, fix EXIF orientation issues, and save as optimized JPEG with quality set to 85.

Handle CPU-bound work in async contexts

Offload image processing to separate threads using Starlette's run_in_threadpool to prevent blocking the async event loop during computationally intensive Pillow operations.

Generate secure unique filenames

Create UUID4 filenames instead of using client-provided names to prevent file collisions, directory traversal attacks, and security issues from malicious file names.

🔒 Security & Validation 3 insights

Validate actual file content

Verify uploaded files are valid images by attempting to open them with Pillow and catching UnidentifiedImageError rather than trusting client-provided Content-Type headers.

Enforce upload size limits

Configure a maximum file size setting (default 5MB) and validate content length after reading to protect the server from excessive memory consumption and denial-of-service attacks.

Secure API schemas

Remove image_file fields from Pydantic update schemas to prevent users from manipulating file paths directly through JSON endpoints, restricting changes to dedicated upload endpoints only.

Safe File Operations 3 insights

Maintain safe transaction ordering

Save new image files to disk before updating the database, and only delete old files after successful database commits to prevent losing user profile pictures if transactions fail.

Use dedicated upload endpoints

Create separate PATCH endpoints using UploadFile for multipart/form-data rather than mixing binary file data with JSON payloads, keeping concerns clean and manageable.

Implement proper cleanup

Delete physical profile picture files when users upload replacements or delete their accounts, but only after confirming database updates succeed to avoid orphaned files or broken references.

Bottom Line

Validate file integrity with Pillow instead of trusting client headers, process images in thread pools to avoid blocking async endpoints, and always delete old files after database commits succeed to prevent permanent data loss.

More from Corey Schafer

View all