Eisen
Eisen

Reputation: 167

Call marshmallow validated GET endpoint with List parameter

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

Answers (2)

Max
Max

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

Eisen
Eisen

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

Related Questions