bauerji / flask-pydantic

flask extension for integration with the awesome pydantic package
MIT License
363 stars 58 forks source link

Internal Server Error when trying to deserialise body when Content-Type is not application/json #3

Closed adityaguru149 closed 4 years ago

adityaguru149 commented 4 years ago

I get the following error when trying to hit "/register" with incorrect Content-Type as text/plain

[2020-06-11 10:15:12,484] ERROR in app: Exception on /register [POST] Traceback (most recent call last): File "/home/aguru/.local/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/home/aguru/.local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/aguru/.local/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/home/aguru/.local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/home/aguru/.local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "/home/aguru/.local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request return self.view_functions[rule.endpoint](req.view_args) File "/usr/local/lib/python3.7/dist-packages/flask_pydantic/core.py", line 131, in wrapper b = body(body_params) TypeError: ModelMetaclass object argument after ** must be a mapping, not NoneType 127.0.0.1 - - [11/Jun/2020 10:15:12] "POST /register HTTP/1.1" 500 -

Postman Screenshot from 2020-06-11 10-26-32

Code

from flask import Flask
from flask_pydantic import validate
from pydantic import BaseModel
from typing import Optional

app = Flask(__name__)

class BodyModel(BaseModel):
    service: str
    details: Optional[str]

class ResponseModel(BaseModel):
    uuid: str
    status: Optional[str]

@app.route("/register", methods=["POST"])
@validate(body=BodyModel)
def register_service_request():
    # save model to DB
    uuid = "uuid"

    return ResponseModel(uuid=uuid), 202

app.run()

I would have expected either:

  1. Should it be Bad Request (or may be Validation Error) instead? We are expecting a json here but got text?
  2. Try to get_json (force=True) even when Content-Type is not application/json. (Does not seem to be proper way of doing it though)

@bauerji Your thoughts?

bauerji commented 4 years ago

Hello @adityaguru149,

I propose another solution: since you defined a request body model, you are expecting application/json content type. If the request has some other content type then the response should have 415 - unsupported media type status.