Reputation: 678
In flask-restplus, I defined response body data structure using api.model
decorator, I am expecting the output of api function should yield exact data structure that I defined. I have lack of ideas how to do it exactly. Can anyone point me out how to validate json response content in flask? any workaround to validate json response output with defined schema? any thoughts?
current output:
here is current output after I made POST request to api function: myfunc
:
"{\n\r\n \"score\": [72.188, 62.0955, 19.3374, 45.6086, 77.8891, 22.188, 45.9938, 91.9877, 14.2527, 1.5408, 62.5578],\n\r\n \"category\": \"low\",\n\r\n \"direction\": \"text description\",\n\r\n \"is_ready\": true,\n\r\n \"features_used\": {\n\r\n \"name\": \"heart_rate\",\n\r\n \"value\": null,\n\r\n \"range_value\": [3.6667, 5, 6.3333, 7.6667, 9, 10.3333, 11.6667, 13, 14.3333],\n\r\n \"range_frequency\": [0.0024, 0, 0.0049, 0.0016, 0.0073, 0.0195, 0.0098, 0.0138, 0.9406],\n\r\n \"level\": 0\n\r\n }\n\r\n} \n"
question is the format of the current output didn't yield what response body defined. How to fix this? how to validate json response content in flask? any possible way to make this happen? thanks
minimal api with specified response json body
from flask import Flask, jsonify
from flask_restplus import Namespace, Resource, fields, reqparse
from flask_restplus import Api
app = Flask(__name__)
api = Api(app)
ns = api.namespace('hello-world')
used_features = {}
used_features['name'] = fields.String(attribute='name')
used_features['value'] = fields.Integer(attribute='value')
used_features['range_value'] = fields.List(
fields.Integer, attribute='range_value')
used_features['range_frequency'] = fields.List(
fields.Integer, attribute='range_frequency')
used_features['level'] = fields.Integer(attribute='level')
used_features_payload = api.model('feature_payload', used_features)
response_body= api.model('response', {
'score': fields.Integer,
'category': fields.String,
'direction': fields.String,
'is_ready': fields.Boolean,
'features_used': fields.Nested(used_features_payload)
})
objective:
I want to validate the JSON schema of the current output. How can I validate function output with response body JSON schema? any idea?
Upvotes: 1
Views: 1766
Reputation: 941
you could validate your response with marshmallow. I figured out your problem as follow:
from marshmallow import Schema, fields, post_load
from marshmallow import EXCLUDE
import json
from flask import jsonify
class Feature:
def __init__(self, name, value, range_value, range_frequency, importance):
self.name = name
self.value = value
self.range_value = range_value
self.range_frequency = range_frequency
self.importance = importance
class FeatureSchema(Schema):
value = fields.Integer()
name = fields.Str()
importance = fields.Integer()
range_value = fields.List(fields.Integer)
range_frequency = fields.List(fields.Integer)
@post_load
def make_feature(self, data, **kwargs):
return Feature(**data)
class App(object):
def __init__(self, score, category, guidance, readiness, features_used):
self.score = score
self.category = category
self.guidance = guidance
self.readiness = readiness
self.features_used = features_used
class RespSchema(Schema):
score = fields.Integer()
category = fields.Str()
guidance = fields.Str()
readiness = fields.Boolean()
features_used = fields.List(fields.Nested(FeatureSchema))
@post_load
def make_app(self, data, **kwargs):
return App(**data)
marshmallow works pretty good for data validation.
Upvotes: 2
Reputation: 2046
Ignoring the technical details in your code,
To validate your JSONschema or any defined schema you can use JSONscheme package.
This package is fairly simple to use. Quoting the part of the usage here.
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}
you define the schema like this, and you can just pass your object to validate against this schema. if it doesn't match, the validator will throw and exception.
from jsonschema import validate
validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
Upvotes: 0