jyson
jyson

Reputation: 285

python marshmallow: any workaround to validate nested request JSON?

I want to validate nested request JSON with marshmallow, I pretty much followed its documentation to validate my request JSON data. After I several attempts, I think using marshmallow to validate complex JSON data is right way. However, I got a validation error from marshmallow as follow:

updated error message

> PS C:\Users\jyson\immunomatch_api> python .\json_validation.py
> Traceback (most recent call last):   File ".\json_validation.py", line
> 58, in <module>
>     app = schema.load(app_data)   File "C:\Users\jyson\AppData\Local\Programs\Python\Python37\lib\site-packages\marshmallow\schema.py",
> line 723, in load  
>     data, many=many, partial=partial, unknown=unknown, postprocess=True   File
> "C:\Users\jyson\AppData\Local\Programs\Python\Python37\lib\site-packages\marshmallow\schema.py",
> line 904, in _do_load
>     raise exc marshmallow.exceptions.ValidationError: {'_schema': ['Invalid input type.']}

update

before I got positional argument error because I implicitly define features like def __init__(self, age, gender, features) instead of doing hard code in def init(self, age, gender, IL10, CRP). why I have above error? any quick thought? thanks

my attempt for json validation with marshmallow:

from marshmallow import Schema, fields, post_load
from marshmallow import EXCLUDE
import json

class Feature(object):
    def __init__(self, value, device):
        self.value = value
        self.device= device

class FeatureSchema(Schema):
    value = fields.Str()
    device= fields.Str()

    @post_load
    def make_feature(self, data, **kwargs):
        return Feature(**data)

class App(object):
    def __init__(self, age, gender, features):
        self.age = age
        self.gender = gender
        self.features = features

class AppSchema(Schema):
    age = fields.Str()
    gender = fields.Str()
    features = fields.Nested(FeatureSchema)

    @post_load
    def make_app(self, data, **kwargs):
        return App(**data)

json_data = """{

"body": {
    "gender": "M",
    "PCT4": {
      "value": 12,
      "device": "roche_cobas"
    },
    "IL10": {
      "value": 12,
      "device": "roche_cobas"
    },
    "CRP": {
      "value": 12,
      "device": "roche_cobas"
    },
     "OM10": {
      "value": 120,
      "device": "roche_bathes"
    }
  }
}"""

app_data = json.loads(json_data)

schema = AppSchema(unknown=EXCLUDE, many=TRUE)
app = schema.load(app_data)

print(app.data.features.value)

why I have the above error? what's the right way to validate nested JSON? why I am having unknown field error? any possible thought to get rid of error above? thanks

Upvotes: 1

Views: 4548

Answers (1)

iamkhush
iamkhush

Reputation: 2592

The error clearly mentions the issue

marshmallow.exceptions.ValidationError: {'OM10': ['Unknown field.'], 'CRP': ['Unknown field.'], 'IL10': ['Unknown field.'], 'PCT4': ['Unknown field.']}

Marshmallow's Schema doesn't understand the field, since you have not declared it into your schema, and by default, Marshmallow will raise an error if it finds an Unknown Field

An easy fix is to EXCLUDE them as looking at your code, it seems you dont need it anyway.

I would suggest passing in unknown argument as EXCLUDE when instantiating it.

from marshmallow import EXCLUDE
schema = AppSchema(unknown=EXCLUDE)

More information can be found here - https://marshmallow.readthedocs.io/en/stable/quickstart.html#handling-unknown-fields

Upvotes: 1

Related Questions