marshmallow-code / flask-smorest

DB agnostic framework to build auto-documented REST APIs with Flask and marshmallow
https://flask-smorest.readthedocs.io
MIT License
660 stars 73 forks source link

Multiple File upload thought form-data #474

Open relyativist opened 1 year ago

relyativist commented 1 year ago

I'm currently using flask_smorest.fields.Upload to handle file uploads, but this only allows selecting a single file. Is it possible to upload many files?

I am trying to upload multiple zip archives serializing request with flask_smorest.fields.Upload, in resources im use blueprint arguments with @blp.arguments(UploadShema, location="files") and getting file with f = files["data"]. But the issue is f returns only first file added thought form-data.

How could this issue be resolved?

lafrech commented 1 year ago

You can put as many fields as you want in the arguments schema (data_1, data_2,...).

https://github.com/marshmallow-code/flask-smorest/blob/a6df3cf4e460b8629ac52583883a286ba155c537/tests/test_arguments.py#L265-L275

relyativist commented 1 year ago

@lafrech Yes, and I am using it for another file field in form-data. However, what if I have 10-20 zip archives and I want to serialize them in list-type instance file_1 = Upload(). What if I am not assume how much files will be uploaded. And want to have a list of all uploaded files in one row of upload filed of form-data image.

Somthing like this file_1 = fields.List(Upload()) @blp.arguments(MultipartSchema(many=True), location="files") .

alwin48 commented 12 months ago

I think you can use:

class MultipartFileSchema(Schema):
    file_list = fields.List(Upload())

and

@blp.arguments(MultipartSchema(many=True), location="files")
def func(response): 
    files = response['file_list']
    for file in files:
        any operation
zhangwenting0224 commented 5 months ago

@alwin48 The method mentioned is a feasible one, but here's a method that's closer to what we actually want. Here's how I did it, sharing it for everyone's reference.

from marshmallow_dataclass import class_schema    
from flask_smorest.fields import Upload
from marshmallow import fields

@dataclass
class MultipartFile(BaseSchema):
    files: List[FileStorage] = field(metadata={"marshmallow_field": fields.List(Upload())})
MultipartFileSchema = class_schema(MultipartFile)

e.g @blp.arguments(MultipartFileSchema, location="files")