处理特定的个性化异常/条件(FastAPI, Pydantic模型,预测模型部署)



我正在使用Pydantic模型用于FastAPI的数据验证为预测部署一个机器学习模型,所以我想处理以下异常/条件:

  • 给出多个输入,如果其中一个不符合功能要求(类型,长度…)抛出特定无效输入的异常,但显示其他有效输入的输出

我想要实现的

输入:


[
{
"name":"John",
"age": 20,
"salary": 15000
},
{
"name":"Emma",
"age": 25,
"salary": 28000
},
{
"name":"David",
"age": "test",
"salary": 50000
},
{
"name":"Liza",
"age": 5000,
"salary": 30000
}
]

输出:


[
{
"prediction":"Class1",
"probability": 0.88
},
{
"prediction":"Class0",
"probability": 0.79
},
{
"ËRROR: Expected type int but got str instead"
},
{
"ËRROR: invalid age number"
}
]

我的基本模型类:

from pydantic import BaseModel, validator
from typing import List
n_inputs = 3
n_outputs = 2

class Inputs(BaseModel):
name: str
age: int
salary: float

class InputsList(BaseModel):
inputs: List[Inputs]
@validator("inputs", pre=True)
def check_dimension(cls, v):
for point in v:
if len(point) != n_inputs:
raise ValueError(f"Input data must have a length of {n_inputs} features")
return v

class Outputs(BaseModel):
prediction: str
probability: float
class OutputsList(BaseModel):
output: List[Outputs]
@validator("output", pre=True)
def check_dimension(cls, v):
for point in v:
if len(point) != n_outputs:
raise ValueError(f"Output data must a length of {n_outputs}")
return v

问题是:→我如何用上面的代码实现这种异常或条件处理?

您可以通过解码提交的JSON并自己处理列表来实现这一点。然后,当期望的数据类型和提交的数据类型不匹配时,您可以通过Pydantic捕获ValidationError引发。

from fastapi import FastAPI, Request
from pydantic import BaseModel, validator, ValidationError, conint
from typing import List
app = FastAPI()

class Inputs(BaseModel):
name: str
age: conint(lt=130)
salary: float


@app.post("/foo")
async def create_item(request: Request):
input_list = await request.json()
outputs = []

for element in input_list:
try:
read_input = Inputs(**element)
outputs.append(f'{read_input.name}: {read_input.age * read_input.salary}')
except ValidationError as e:
outputs.append(f'Invalid input: {e}')

return outputs

将列表提交给/foo端点将生成(在本例中)一个已处理值的列表或一个错误:

['John: 300000.0', 
'Emma: 700000.0', 
'Invalid input: 1 validation error for Inputsnagen  value is not a valid integer (type=type_error.integer)', 
'Invalid input: 1 validation error for Inputsnagen  ensure this value is less than 130 (type=value_error.number.not_lt; limit_value=130)'
]