How to disable schema checking in FastAPI?

Viewed 5527

I am migrating a service from Flask to FastAPI and using Pydantic models to generate the documentation. However, I'm a little unsure about the schema check. I'm afraid there will be some unexpected data (like a different field format) and it will return an error.

In the Pydantic documentation there are ways to create a model without checking the schema: https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation

However, as this is apparently instantiated by FastAPI itself, I don't know how to disable this schema check when returning from FastAPI.

3 Answers

You could return Response directly, or with using custom responses for automatic convertion. In this case, response data is not validated against the response model. But you can still document it as described in Additional Responses in OpenAPI.

Example:

class SomeModel(BaseModel):
    num: int


@app.get("/get", response_model=SomeModel)
def handler(param: int):
    if param == 1:  # ok
        return {"num": "1"}
    elif param == 2:  # validation error
        return {"num": "not a number"}
    elif param == 3:  # ok (return without validation)
        return JSONResponse(content={"num": "not a number"})
    elif param == 4:  # ok (return without validation and conversion)
        return Response(content=json.dumps({"num": "not a number"}), media_type="application/json")

You can set the request model as a typing.Dict or typing.List

from typing import Dict

app.post('/')
async def your_function(body: Dict):
  return { 'request_body': body}

FastAPI doesn't enforce any kind of validation, so if you don't want it, simply do not use Pydantic models or type hints.

app.get('/')
async def your_function(input_param):
  return { 'param': input_param }

# Don't use models or type hints when defining the function params.
# `input_param` can be anything, no validation will be performed.

However, as @Tryph rightly pointed out, since you're using Pydantic to generate the documentation, you could simply use the Any type like so:

from typing import Any
from pydantic import BaseModel

class YourClass(BaseModel):
    any_value: Any

Beware that the Any type also accepts None, making in fact the field optional. (See also typing.Any in the Pydantic docs)

Related