Reputation: 381
I have a problem with my API on Flask, using spectree.
I have one endpoint with one "POST" method, which takes some data, validates it, and if successful, returns {"status": "OK"}
, and in case of validation error, returns a 400 code and a message that there was a validation error. It is rather not what I have, but what I wanted to achieve. I suggest taking a look at the code to better understand what I mean:
from flask import Flask
from spectree import SpecTree, Response
from pydantic import BaseModel
class Error(BaseModel):
code:int = 400
message:str = 'Validation Failed'
class Unit(BaseModel):
id: int
app = Flask(__name__)
api = SpecTree('flask', app=app, title='API', version='v1.0', path='docs')
@app.post('/imports')
@api.validate(json=Unit, validation_error_status=400, resp=Response(HTTP_400=Error))
def imports():
return {'status': 'OK'}, 200
That is, as you can see, following the documentation, I set validation_error_status=400
so that when validation fails, the client receives a response with a 400 code (wow?). I also set resp=Response(HTTP_400=Error)
so that when a 400 error occurs, the client receives an Error response. Thus, on a validation error, the API client should receive a response corresponding to the Error model (see below)
Now, if I send a request that is not valid, that is, id
will not be int, but for example "fkfld", I will receive the following response:
[
{
"loc": [
"id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
I thought the answer would be:
{
"code": 400,
"message": "Validation Failed"
}
I use:
I tried very hard to understand what my mistake was, but I could not. I've read the documentation, but my problem is only related to:
What is Response and how to use it?
To build a response for the endpoint, you need to declare the status code with format HTTP_{code} and corresponding data (optional).
Please help me figure this out, I really want to understand my mistakes and how to do it right.
Upvotes: 1
Views: 556
Reputation: 11
You can achieve this by using the before_handler.
def before_handler(req, resp, err, instance):
"""Change the error message to the format we expect. This is only for validation errors"""
if err:
resp.text = json.dumps({"error": "ValidationError", "message": str(err)})
spec = SpecTree("falcon", validation_error_status=400, before=before_handler)
And if you specify HTTP_400=SomeErrorModel in your @spec.validate(), your custom error will get validated on that model as well.
Upvotes: 0