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

[Bug] Dataclass optional not working in validate query #105

Closed
weiztech opened this issue Jul 5, 2022 · 3 comments · Fixed by #119
Closed

[Bug] Dataclass optional not working in validate query #105

weiztech opened this issue Jul 5, 2022 · 3 comments · Fixed by #119
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@weiztech
Copy link

weiztech commented Jul 5, 2022

Describe the bug
I'm following this tutorial https://sanic.dev/en/plugins/sanic-ext/validation.html#implementation .
with define dataclass attribute with optional paramater,
it will return 400 , if the query params q have value ex q=123123
without value it will work without problem

I also found the same issue when using pydantic

Screenshots
Screen Shot 2022-07-05 at 16 21 59

To Reproduce

from dataclasses import dataclass, asdict
from typing import Optional

from sanic import Sanic
from sanic.response import json
from sanic_ext import validate


app = Sanic("Sanic-APP")


@dataclass
class SearchParams:
    q: Optional[str] = None


@app.route("/")
@validate(query=SearchParams)
async def handler(request, query: SearchParams):
    return json(asdict(query))

Expected behavior
when the dataclass attribute is Optional, it should not error when we send the query params with value ex ?q=123456

Environment (please complete the following information):

  • OS: Mac Catalina v10.15.7
  • Browser Chrome
  • Version 103.0.5060.53
@miss85246
Copy link

miss85246 commented Jul 7, 2022

@weiztech Hi, there.
In GET method, One parameter can have multiple values, like this:

http://localhost:3000/?q=1&q=2&q=3

Most of the time, you don't need to use this feature. one parameter can have only one value.

So, sanic do some process in RequestParameters object.

def get(self, name: str, default: Optional[Any] = None) -> Optional[Any]:
    """Return the first value, either the default or actual"""
    return super().get(name, [default])[0]


def getlist(self, name: str, default: Optional[Any] = None) -> Optional[Any]:
    """
    Return the entire list
    """
    return super().get(name, default)
print(request.args.get("q"))
# 1

print(request.args.getlist("q"))
# [1, 2, 3]

Of course, all of these are based on the RequestParameters operations.

If you print request.args, you will see:

print(request.args)
# {'q': ['1', '2']}
# {'q': ['1']}

It's a dict whose value is a list.

And In sanic-ext validator, the do_validation function use request.args as the source of data. You got the validation Error is merited.

Now, you can use dataclass like this to solve this problem temporarily.

@dataclass
class SearchParams:
    q: Optional[List[str]] = None

I hope this will help you.

@weiztech
Copy link
Author

weiztech commented Jul 9, 2022

@miss85246 ,

Thanks for let me know the temporary fix. it's really help me 😊😊
Hope the issue will be fixed in future

@prryplatypus prryplatypus added bug Something isn't working good first issue Good for newcomers labels Aug 6, 2022
@ahopkins
Copy link
Member

So, what makes this one a little different is the Optional. If you left that part off it should work. A fix is coming shortly though for the optional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants