Reputation: 167
I have a marshmallow schema validation like this:
class MyFilterSchema(Schema):
ids = fields.List(fields.Str(validate=non_empty), required=True)
Then in my endpoint I call the schema validation: MyFilterSchema().load(flask.request.args)
Now I try to call the HTTP GET endpoint which is using this validation. But I get 'ids': ['Not a valid list.']
I tried different ways:
/myendpoint?ids=1,2,3
/myendpoint?ids=1&ids=2
/myendpoint?ids=[1,2]
but no luck. How must the endpoint be called that marshmallow recognizes my GET parameter as list?
Upvotes: 2
Views: 3564
Reputation: 755
To build on Eisen's answer, to support all of Mashmallow's validation and deserialization you need to do a bit more:
class DelimitedListField(fields.List):
def __init__(self, cls_or_instance: typing.Union[fields.Field, type], **kwargs):
super().__init__(cls_or_instance, **kwargs)
def _deserialize(self, value, attr, data, **kwargs) -> typing.List[typing.Any]:
try:
logger.info(f"value={value}")
list = value.split(",")
logger.info(f"list={list}")
return super()._deserialize(list, attr, data, **kwargs)
except AttributeError:
raise marshmallow.exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)
Upvotes: 2
Reputation: 167
One way is to use a custom implementation of a validation field instead of the integrated list field.
class DelimitedListField(fields.List):
def _deserialize(self, value, attr, data, **kwargs):
try:
return value.split(",")
except AttributeError:
raise exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)
This can be used in the schema as follow:
class MyFilterSchema(Schema):
ids = DelimitedListField(fields.Str(validate=non_empty), required=True)
and would accept calls in the format:
/myendpoint?ids=1,2,3
Upvotes: 3