This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String "NaN" is coerced to float value when saving data objects (which breaks retrieving the objects) #4589
Comments
My goal is not to accept NaN values but to block the user from sending these to make sure the get api would always work. |
Still occurs in fastapi 0.74.0 |
import math
from typing import List
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class RegularFloat(float):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if not math.isfinite(float(v)):
raise ValueError("Invalid float.")
return cls(v)
class DataModel(BaseModel):
a_string_value: str
a_float_value: RegularFloat
stored_objects: List[DataModel] = []
@app.get("/", response_model=List[DataModel])
async def get_objects():
return stored_objects
@app.post("/")
async def save_object(to_save: DataModel):
return stored_objects.append(to_save)
if __name__ == '__main__':
uvicorn.run(
"main:app",
workers=1
) Example code used to fix my application. |
Note that math.isfinite was used to also catch "Inf", "-Inf" and similar values. |
So how about using Decimal instead of float |
Decimal and StrictFloat are indeed also working. I will change all floats on all my models to Decimal to assure that the objects can be returned. Thank you for the help. |
Thanks for the report @samv-yazzoom! And thanks for the help @yinziyan1206. I see how this behavior feels unexpected, it does to me. I made a PR to Pydantic adding support for more restrictive I would like for Let's see what happens with that PR to Pydantic. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
First Check
Commit to Help
Example Code
Description
I have an application where one of the models contains a field that is a float value.
My database to back this is a mongodb instance.
In the example this is mocked by a simple list; make sure to use a single worker thread when trying to test this locally (uvicorn main:app --workers 1).
A user once tried to send a "NaN" float value and my application accepted it and stored it in mongodb.
What I think is happening is that the string value that is posted is being coerced into a float and float("NaN") gives this annoying value.
This stored value of NaN cannot be returned by subsequent get calls.
Example calls to show the problematic behavior when NaN values are accepted:
curl localhost:8000
[]
curl localhost:8000 -H 'Content-Type: application/json' -d '{"a_string_value": "object 1", "a_float_value": 0.5}'
curl localhost:8000
[{"a_string_value":"object 1","a_float_value":0.5}]
curl localhost:8000 -H 'Content-Type: application/json' -d '{"a_string_value": "object 1", "a_float_value": "NaN"}'
curl localhost:8000
Internal Server Error
ValueError: Out of range float values are not JSON compliant
I could add a validation on each of my models that use a float value or create an extension of a float that I then use in my models but this still feels like a risky way of fixing the issue.
If I forget checking for NaN value coercion on any of my models, a user could break the get behaviour by posting a "NaN" value.
This was cleared by @tiangolo for security issues.
Operating System
Linux
Operating System Details
Ubuntu 20
FastAPI Version
0.73.0
Python Version
3.9.10
Additional Context
This issue was first reported as a security issue but was cleared.
The text was updated successfully, but these errors were encountered: