upload endpoint inside a Flask blueprint. It preserves the validation steps and adds structured logging, appropriate status codes, and a top-level exception handler.
- Input validation layers:
- Presence of
imagepart inrequest.files. - Non-empty filename and
secure_filename()usage. - Extension whitelist check.
- Binary content validation using
imghdr.what. - Final verification with Pillow (
Image.verify()).
- Presence of
- Parameter validation:
qualityis parsed as an integer with a safe default and bounds check (0–100).
- Image processing:
- Decoding via OpenCV (
cv2.imdecode) and re-encoding with the requested JPEG quality. - Re-validation of processed bytes with Pillow before sending.
- Decoding via OpenCV (
- Error handling and logging:
- Specific client errors return 400 with helpful messages.
- Processing failures return 500 where appropriate.
logger.exceptionin the outerexceptcaptures stack traces for unexpected errors.
Always validate both the filename/extension and the file content. File extension checks alone are not sufficient because an attacker can rename arbitrary files.
- Use Postman, curl, or similar to POST multipart/form-data with a file field named
image. - Include an optional
qualityform field to control JPEG quality (0–100). - Test both success and failure cases: missing file, invalid extension, corrupted image, invalid quality value.
- Inspect server logs (INFO/ERROR) for contextual messages.
- Flask documentation: https://flask.palletsprojects.com/
- Gunicorn: https://gunicorn.org/
- uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/
- Pillow (PIL): https://python-pillow.org/
- OpenCV-Python tutorials: https://docs.opencv.org/
- imghdr module: https://docs.python.org/3/library/imghdr.html
- Postman Essentials (example testing workflow): https://learn.kodekloud.com/user/courses/postman-essentials