Fastapi: [QUESTION] How can I validate request body as is?

Created on 25 Apr 2019  路  8Comments  路  Source: tiangolo/fastapi

Description

How can I validate request body as is?

Additional context

I try to use fastapi.
First I wrote simple api, as shown below.

from fastapi import FastAPI, Body


app = FastAPI()


@app.post("/test")
def test(i: int = Body(..., embed=True),
         f: float = Body(..., embed=True),
         s: str = Body(..., embed=True),
         b: bool = Body(..., embed=True)):
    return {'int': i, 'float': f, 'str': s, 'bool': b}

And request with valid body shown below.
I think this result is correct.

$ curl localhost:8000/test -X POST -d '{"i": 1, "f": 1.0, "s": "abc", "b": true}'
{"int":1,"float":1.0,"str":"abc","bool":true}

Then, I try to request with invalid body I think.
Result is shown below.

$ curl localhost:8000/test -X POST -d '{"i": true, "f": true, "s": true, "b": true}'
{"int":1,"float":1.0,"str":"True","bool":true}

true value is converted to each types(int, float, str).

When I want to validate request body as is,
how can I do that?

question

Most helpful comment

The request is validated by Pydantic. If you want to make sure that each type is exactly that type before doing any conversion, you can create a sub-class for each type, and then use Pydantic validators to ensure that it's exactly that type.

Check the example for StrictStr. It ensures that the value is an instance of str before trying to convert it to something else: https://pydantic-docs.helpmanual.io/#custom-data-types

All 8 comments

That's actually part of the nature of Python itself:

>>> 1 == int(True)
True

If you need to check more strictly for each data type, you can declare the body as a Pydantic model (I would suggest you do it either way, it would simplify a lot your code): https://fastapi.tiangolo.com/tutorial/body/

And then you can use Pydantic validators to ensure your values are of the exact type you need: https://pydantic-docs.helpmanual.io/#validators

Also, have in mind that in JavaScript (and therefore in JSON) there's no real distinction between int and float, both are just Number.

Thank you for your comment.

I think Pydantic validators are only applied after type conversion.
Should we depend on Python typing in FastAPI? (not JSON typing)

@k-tahiro when you declare a Python type in a parameter, it is validated with Pydantic. FastAPI uses Pydantic internally for that.

What do you mean with JSON typing? If you refer to the difference between Number in JSON and float in Python, you can just use Python types.

I think there should be type conversion JSON to Python depends on JSON typing.
Just like below:

|JSON|Python|
|:--|:--|
|string|str|
|number|int|
|number|float|
|boolean|bool|

But Pydantic? type conversion is just like below:

|JSON|Python|
|:--|:--|
|string or number or boolean|str|
|string or number or boolean|int|
|string or number or boolean|float|
|string or number or boolean|bool|

My first question is how can I validate request body before Pydantic? type conversion.

The request is validated by Pydantic. If you want to make sure that each type is exactly that type before doing any conversion, you can create a sub-class for each type, and then use Pydantic validators to ensure that it's exactly that type.

Check the example for StrictStr. It ensures that the value is an instance of str before trying to convert it to something else: https://pydantic-docs.helpmanual.io/#custom-data-types

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

Is it possible to make sure with FastApi validation that an int is only actually an int and not a string or a float/double?

For example, if I send "10", or 10.5 it goes through as 10.

I can also send fields that I don't want. What if I only want to receive a string, but receive several (or receive an extra list, etc); is there already an implementation that verifies this?

Sure, see here https://pydantic-docs.helpmanual.io/usage/types/#strict-types @carlosvbhenriques

Was this page helpful?
0 / 5 - 0 ratings