flask_accepts
flask_accepts copied to clipboard
What is the best practice for file uploads?
One of the endpoints Im writing is based on file upload. What is the best way to use the accepts decorator for this?
File upload is probably out of scope for flask_accepts, since its goal is to make marshmallow and flask_restx play together. I think the best solution is to write your own accepts_file() decorator on top of flask_restx (example here).
Example solution:
from functools import wraps
from flask import abort
from flask_restx import Namespace
from flask_restx.reqparse import RequestParser
from werkzeug.datastructures import FileStorage
def accepts_files(*, api: Namespace, argument_name: str = "files", required: bool = True):
"""
Decorator that adds a file upload entry to the swagger documentation.
The decorated method must accept an `argument_name` keyword argument,
whose value will be the list of files (more precisely `werkzeug.datastructures.FileStorage`
objects) that were sent by the client in the `argument_name` form part.
"""
file_upload_parser = RequestParser()
file_upload_parser.add_argument(name=argument_name, type=FileStorage, location="files", action="append", required=required)
def decorator(func):
@wraps(func)
def inner(*args, **kwargs):
files = None
try:
data = file_upload_parser.parse_args()
files = data[argument_name]
except Exception:
pass
if files is None and required:
abort(400)
return func(*args, **kwargs, **{argument_name: files})
return api.expect(file_upload_parser)(inner)
return decorator