factset/quart-openapi

Integer validation error

Opened this issue · 2 comments

I was testing this example code:

from quart import request,jsonify
from quart_openapi import Pint,Resource

app = Pint(__name__)

expected = app.create_validator('sample_request', {
  'type': 'object',
  'properties': {
    'foobar': {
      'type': 'string'
    },
    'baz': {
      'oneOf': [
        { 'type': 'integer' },
        { 'type': 'number', 'format': 'float' }
      ]
    }
  }
})
@app.route('/')
class Testing(Resource):
  @app.expect(expected)
  async def post(self):
    return jsonify({'message': 'OK'})
if __name__ == '__main__' :
  app.run(debug=True)

Then send this request:

curl -X POST -d '{"foobar":"ss","baz":123}' -H "Content-Type: application/json" http://127.0.0.1:5000 

I got this respond:

HTTP/1.1 400 
content-type: application/json
content-length: 235
date: Sun, 16 Dec 2018 21:00:01 GMT
server: hypercorn-h11

{
  "message": "Request Body failed validation",
  "error": {
    "msg": "123 is valid under each of {'type': 'number', 'format': 'float'}, {'type': 'integer'}",
    "value": 123,
    "schema": {
      "oneOf": [{
        "type": "integer"
      }, {
        "type": "number",
        "format": "float"
      }]
    }
  }
}

But I was expecting {'message':'OK'} respond.
It works with float value for baz key.

Funny note: at respond in msg it says 'is valid' !

The integer validation part works well individually (gives error when passing float or string in baz key as expected) :

'baz': {
     'oneOf': [
       { 'type': 'integer' },
      # { 'type': 'number', 'format': 'float' }
     ]
   }

But when using the float validation (should not accept integer) :

'baz': {
     'oneOf': [
      # { 'type': 'integer' },
       { 'type': 'number', 'format': 'float' }
     ]
   }

but accepts integer! (tested with 123 value)
So the problem should be in { 'type': 'number', 'format': 'float' } and oneOf functionality.

@ehsanonline: Despite the fact that you find a workaround for yourself, I would like to explain why you got the validation error.

The reason is not in Quart-OpenAPI itself, but at jsonschema. JSONSchema (which is used for validtion) has 2 keywords for describing several supported cases:

  • anyOf validates that any (at least one) schema defined by this keyword's value should pass.
  • oneOf validates that only one schema defined by this keyword's value should pass.

123 is a valid over both your schemas (it can be a string and an integer), so validation with oneOf fails...