Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the best practice for file uploads? #84

Open
datavistics opened this issue Jun 14, 2020 · 2 comments
Open

What is the best practice for file uploads? #84

datavistics opened this issue Jun 14, 2020 · 2 comments

Comments

@datavistics
Copy link

One of the endpoints Im writing is based on file upload. What is the best way to use the accepts decorator for this?

@volfpeter
Copy link
Contributor

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).

@volfpeter
Copy link
Contributor

volfpeter commented Apr 9, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants