shevron
shevron

Reputation: 3663

Marshmallow schema: allow any extra field as long as its name matches a pattern

I am building an API endpoint, and using Marshmallow for input validation and marshaling. One of the objects I want to accept has some specific fields, but will also accept additional fields as long as the field name begins with x-. So for example:

{
  "name": "Bob Paulson",  // a strict, required field
  "email": "[email protected]",  // a strict, required field
  "x-dob": "1980-10-11" // not a part of the explicit schema but accepted because it begins with 'x-'
}

Is there a way to specify this in Marshmallow?

Upvotes: 0

Views: 2643

Answers (1)

casraf
casraf

Reputation: 21694

You may use @pre_load to put these fields on an extras field (for example), which may contain any data you want, see the Marshmallow docs about Extending Schema.

from marshmallow import Schema, fields, ValidationError, pre_load


class PersonSchema(Schema):
    name = fields.Str()
    email = fields.Str()
    extra = fields.Dict()

    @pre_load
    def unwrap_envelope(self, data, **kwargs):
        extra = {}
        rest = {}
        for k, v in data.items():
          if k.startswith('x-'):
            extra[k] = v
          else:
            rest[k] = v
        return {'extra':extra,**rest}


sch = PersonSchema()
person_data = {"name": "John Doe", "email": "[email protected]"}

try:
  res1 = sch.load({**person_data,"dob": "1980-11-11"})
  print(res1)
except ValidationError as err:
  print(err.messages)

try:
  res2 = sch.load({**person_data,"x-dob": "1980-11-11"})
  print(res2)
except ValidationError as err:
  print(err.messages)

The above should fail on the first print, and succeed on the second. See a demo here.

Upvotes: 4

Related Questions