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

Issue with file upload request schema validation #89

Open
nkma-ml opened this issue Aug 26, 2024 · 3 comments
Open

Issue with file upload request schema validation #89

nkma-ml opened this issue Aug 26, 2024 · 3 comments

Comments

@nkma-ml
Copy link

nkma-ml commented Aug 26, 2024

Hello.

I'm trying to add schema validation to an upload file endpoint. It looks as follows:

from pydantic import BaseModel
from quart_schema import DataSource, validate_request
from quart_schema.pydantic import File

class Upload(BaseModel):
    file: File 

@file_content_bp.route("/upload_file", methods=["POST"])
@validate_request(Upload, source=DataSource.FORM_MULTIPART)
async def upload_files(file_upload: Upload):
    file_content = file_upload.file.read()
    logging.info(file_content)
    return {"status":"success"}

When I try to invoke it using the following request:

curl --location 'http://localhost:50505/upload_file' \
--header 'Content-Type: multipart/form-data' \
--form 'file=@"<PATH TO LOCAL FILE>"'

I get the following error:

Traceback (most recent call last):
  File "/localpath/lib/python3.11/site-packages/quart/app.py", line 1403, in handle_request
    return await self.full_dispatch_request(request_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "localpath/lib/python3.11/site-packages/quart/app.py", line 1441, in full_dispatch_request
    result = await self.handle_user_exception(error)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "localpath/lib/python3.11/site-packages/quart/app.py", line 1029, in handle_user_exception
    raise error
  File "/localpath/lib/python3.11/site-packages/quart/app.py", line 1439, in full_dispatch_request
    result = await self.dispatch_request(request_context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/localpath/lib/python3.11/site-packages/quart/app.py", line 1535, in dispatch_request
    return await self.ensure_async(handler)(**request_.view_args)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "localpath/lib/python3.11/site-packages/quart_schema/validation.py", line 170, in wrapper
    return await current_app.ensure_async(func)(*args, data=model, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: upload_files() got an unexpected keyword argument 'data'

Seems like it could be a bug, or am I missing something.
The package versions are:
quart==0.19.6
quart-schema[pydantic]==0.20.0

Hopefully it's not me having a brainfart.

BR,
Niels

@nkma-ml nkma-ml changed the title Issue with file upload schema validation Issue with file upload request schema validation Aug 26, 2024
@ziaxgit
Copy link

ziaxgit commented Aug 26, 2024

Hey, I had a similar type error which I fixed by using the word 'data' as the function parameter name. I'm a complete noob so this might be a long shot but it's worth trying.

Replace

async def upload_files(file_upload: Upload):

With

async def upload_files(data: Upload):

@nkma-ml
Copy link
Author

nkma-ml commented Aug 27, 2024

Hey, I had a similar type error which I fixed by using the word 'data' as the function parameter name. I'm a complete noob so this might be a long shot but it's worth trying.

Replace

async def upload_files(file_upload: Upload):

With

async def upload_files(data: Upload):

That is not it, unfortuanetly. It's also just a parameter name, so would really suprise me.

@Beetroit
Copy link

Beetroit commented Sep 7, 2024

I see what the problem is. When using a validation decorator like @validate_request or @validate_querystring, quart-schema returns specific arguments to your route function, (data for validate_request and query_args for validate_querysting). All you have to do it annotate your route function with the appropriate arg and type and you're good to go.

from pydantic import BaseModel
from quart_schema import DataSource, validate_request
from quart_schema.pydantic import File

class Upload(BaseModel):
    file: File 

@file_content_bp.route("/upload_file", methods=["POST"])
@validate_request(Upload, source=DataSource.FORM_MULTIPART)
async def upload_files(data: Upload):
    file = data.file

    file_content = file.stream.read()
    logging.info(file_content)

    # save the file
    file.save(file.name)

    return {"status":"success"}

Your code can then be rewritten as above.

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

3 participants