Open pype-leila opened 1 year ago
In flask-restx
choices is dumb in the sense it only compares like for like exactly. In your instance, it doesn't work because your choices aren't valid lists, which is the data type you request.
If the lists you expect are known in advance (in the correct order), then you could do something like:
parser = reqparse.RequestParser()
parser.add_argument(
"argList",
dest="arg_list",
type=list,
location="json",
default=[],
choices=[
["one"],
["two"],
["three"],
["one", "two"],
],
required=False,
help=f"An argument list",
)
In that case, those exact lists will be matched and validated.
However, what I expect you actually want is to be able to pass a list that contains any number of valid choices in any order. This is possible, but you need to write your own custom validation function. You can do this for any input but providing a function to the type
field of add_argument()
which provides one of two options: a) The valid value or b) Raises a ValueError
.
In your example, you can do something like this to get a valid list:
ALLOWED_VALUES = ["one", "two", "three"]
def list_validator(x):
if type(x) != list:
raise ValueError(f"'{x}' was not a list.")
if not all(value in ALLOWED_VALUES for value in x):
raise ValueError(f"'{x}' contains one or more invalid choices.")
return x
parser = reqparse.RequestParser()
parser.add_argument(
"argList",
dest="arg_list",
type=list_validator,
location="json",
required=False,
help=f"An argument list"
)
This will then give you the expected behaviour:
curl -X POST -d '{"argList": "one"}' -H "Content-Type: application/json" http://127.0.0.1:5000/args
{
"errors": {
"argList": "An argument list 'one' was not a list."
},
"message": "Input payload validation failed"
}
curl -X POST -d '{"argList": ["one"]}' -H "Content-Type: application/json" http://127.0.0.1:5000/args
{
"data": [
"Args look good!"
]
}
curl -X POST -d '{"argList": ["one", "two"]}' -H "Content-Type: application/json" http://127.0.0.1:5000/args
{
"data": [
"Args look good!"
]
}
curl -X POST -d '{"argList": ["one", "two", "four"]}' -H "Content-Type: application/json" http://127.0.0.1:5000/args
{
"errors": {
"argList": "An argument list '['one', 'two', 'four']' contains one or more invalid choices."
},
"message": "Input payload validation failed"
}
To me, the intuitive behavior -- and what I want to accomplish -- would be to determine whether all items in the provided input are both unique and elements of choices, ie the input list is a subset of choices. I have used a custom validator in my own code to accomplish this, but this still seems like a bug to me. At the very least, there should be explicit documentation of the way it does work.
When defining choices for a list in the JSON data input, validation does not work. This is true if type is
list
or if type isstr
and action is"append"
.Code
Repro Steps (if applicable)
python <file-name>.py
Expected Behavior
I would expect to receive an error message with a disallowed parameter and no error message when providing allowed parameters.
Actual Behavior
An error is returned no matter what is present in the request.
Error Messages/Stack Trace
Environment