fastapi pydantic 响应请求 float无法限制精度的解决方案

245 阅读1分钟

问题描述

使用fastapi写api服务时,对于float类型的响应参数,需要限制输出精度。

环境配置

python==3.6 fastapi==0.75.1

问题还原

fastapi model

class BASE_RESPONSE(BaseModel):
    department:str
    score:float

class PREDICT_RESPONSE(BaseModel):
    recommendations:List[BASE_RESPONSE]
    code:int
    msg:str

原始代码

fastapi main

@app.get("/test")
def test():
    recommendations=[]
    for i in range(5):
        department=str(i)
        score=0.92929292929+i*1e-5
        base_response=BASE_RESPONSE(department=department,score=score)
        recommendations.append(base_response)
    return PREDICT_RESPONSE(recommendations=recommendations,code=200,msg="success")

使用postman响应结果

{
    "recommendations": [
        {
            "department": "0",
            "score": 0.92929292929
        },
        {
            "department": "1",
            "score": 0.9293029292899999
        },
        {
            "department": "2",
            "score": 0.92931292929
        },
        {
            "department": "3",
            "score": 0.9293229292899999
        },
        {
            "department": "4",
            "score": 0.92933292929
        }
    ],
    "code": 200,
    "msg": "success"
}

round / np.around()限制输出

限制在小数点后4位

@app.get("/test")
def test():
    recommendations=[]
    for i in range(5):
        department=str(i)
        score=round(0.92929292929+i*1e-5,4)
        # score=np.around(0.92929292929+i*1e-5,4)
        base_response=BASE_RESPONSE(department=department,score=score)
        recommendations.append(base_response)
    return PREDICT_RESPONSE(recommendations=recommendations,code=200,msg="success")
{
    "recommendations": [
        {
            "department": "0",
            "score": 0.92929292929
        },
        {
            "department": "1",
            "score": 0.9293029292899999
        },
        {
            "department": "2",
            "score": 0.92931292929
        },
        {
            "department": "3",
            "score": 0.9293229292899999
        },
        {
            "department": "4",
            "score": 0.92933292929
        }
    ],
    "code": 200,
    "msg": "success"
}

解决方法

使用float(str(round()))

@app.get("/test")
def test():
    recommendations=[]
    for i in range(5):
        department=str(i)
        score=0.92929292929+i*1e-5
        score=float(str(round(score,4)))
        base_response=BASE_RESPONSE(department=department,score=score)
        recommendations.append(base_response)
    return PREDICT_RESPONSE(recommendations=recommendations,code=200,msg="success")
{
    "recommendations": [
        {
            "department": "0",
            "score": 0.9293
        },
        {
            "department": "1",
            "score": 0.9293
        },
        {
            "department": "2",
            "score": 0.9293
        },
        {
            "department": "3",
            "score": 0.9293
        },
        {
            "department": "4",
            "score": 0.9293
        }
    ],
    "code": 200,
    "msg": "success"
}

Decimal

from decimal import Decimal

@app.get("/test")
def test():
    recommendations=[]
    for i in range(5):
        department=str(i)
        score=0.92929292929+i*1e-5
        score=Decimal(score).quantize(Decimal('0.0000'))
        base_response=BASE_RESPONSE(department=department,score=score)
        recommendations.append(base_response)
    return PREDICT_RESPONSE(recommendations=recommendations,code=200,msg="success")
{
    "recommendations": [
        {
            "department": "0",
            "score": 0.9293
        },
        {
            "department": "1",
            "score": 0.9293
        },
        {
            "department": "2",
            "score": 0.9293
        },
        {
            "department": "3",
            "score": 0.9293
        },
        {
            "department": "4",
            "score": 0.9293
        }
    ],
    "code": 200,
    "msg": "success"
}