SimpleOne
SimpleOne

Reputation: 1076

marshmallow - choose nested schema based on field value and handle fields 'starting with'

I am parsing a file and end up with a dictionary like this:

user_data = {
  "title": "TestA",
  "sects": [
    {
        "type": "cmd",
        "cmd0": {
          "moveX": 12,
          "moveY": 34,
          "action": "fire"
        },
        "session": 9999,
        "cmd1": {
          "moveX": 56,
          "moveY": 78,
          "action": "stop"
        },
        "endType": 0,
      },
      {
        "type": "addUsers",
        "user1": {
          "name": "John",
          "city": "London"
        },
        "user2": {
          "name": "Mary",
          "city": "New York"
        },
        post = "yes"
      }
    ]
}

I am attempting to validate it using marshmallow but not sure how to handle these two things:

  1. With sects the content of each nested dict is dependent on the type (cmd, addUser, etc). Is there a way to pick a schema based on the value of a field?
  2. Is there such a thing as field 'startsWith' to handle the fact that I may have cmd0, cmd1...cmdN?

So, something like the following:

class CmdSchema(schema):
    type = fields.Str()
    cmdN = fields.Dict(...) # Allow cmd1, cmd2, etc
    session = fields.Int()
    endType = fields.Int()

class AddUsersSchema(schema):
    type = fields.Str()
    userN = fields.Dict(...) # Allow user1, user2, etc
    post = fields.Str()

class ParsedFileSchema(schema):
   title = fields.Str()
   sects = fields.Nested(...)   # Choose nested schema based on sects[i]['type']?

Note: I cannot change the format/content of the file I'm parsing and order matters (so I need to retain the order of cmd1, cmd2, etc so they can be processed in the correct order).

Upvotes: 1

Views: 1879

Answers (1)

Jérôme
Jérôme

Reputation: 14714

1/ What you want to achieve is polymorphism. You may want to check out marshmallow-oneofschema.

2/ This does not exist to my knowledge. It shouldn't be too hard to create as a custom validator, though. It might even make it to the core.

Upvotes: 1

Related Questions