我的
GET
端点收到需要满足以下条件的查询参数:
int
1.
可以直接使用 Query(gt=0, lt=10)
。但是,我不清楚如何扩展 Query
来进行额外的自定义验证,例如 2.
。该文档最终导致了 pydantic。但是,当第二次验证 2.
失败时,我的应用程序遇到内部服务器错误。
下面是一个最小范围的示例
from fastapi import FastAPI, Depends, Query
from pydantic import BaseModel, ValidationError, validator
app = FastAPI()
class CommonParams(BaseModel):
n: int = Query(default=..., gt=0, lt=10)
@validator('n')
def validate(cls, v):
if v%2 != 0:
raise ValueError("Number is not even :( ")
return v
@app.get("/")
async def root(common: CommonParams = Depends()):
return {"n": common.n}
以下是按预期工作的请求和失败的请求:
# requsts that work as expected
localhost:8000?n=-4
localhost:8000?n=-3
localhost:8000?n=2
localhost:8000?n=8
localhost:8000?n=99
# request that break server
localhost:8000?n=1
localhost:8000?n=3
localhost:8000?n=5
HTTPException
而不是ValueError
,如此答案的选项1所示。示例:
from fastapi import FastAPI, Depends, Query, HTTPException
from pydantic import BaseModel, validator
app = FastAPI()
class CommonParams(BaseModel):
n: int = Query(default=..., gt=0, lt=10)
@validator('n')
def prevent_odd_numbers(cls, v):
if v % 2 != 0:
raise HTTPException(status_code=422, detail='Input number is not even')
return v
@app.get('/')
async def root(common: CommonParams = Depends()):
return {'n': common.n}
服务器响应(当输入数字非偶数时,例如
n = 1
):
# 422 Error: Unprocessable Entity
{
"detail": "Input number is not even"
}
使用自定义异常处理程序,以处理
ValueError
异常,类似于这个答案和这个答案。示例:
from fastapi import FastAPI, Request, Depends, Query, status
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel, validator
app = FastAPI()
@app.exception_handler(ValueError)
async def validation_exception_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), # optionally, include the pydantic errors
"custom msg": {"Your error message"}}), # optionally, return a custom message
)
class CommonParams(BaseModel):
n: int = Query(default=..., gt=0, lt=10)
@validator('n')
def prevent_odd_numbers(cls, v):
if v % 2 != 0:
raise ValueError('Input number is not even')
return v
@app.get('/')
async def root(common: CommonParams = Depends()):
return {'n': common.n}
服务器响应(当输入数字非偶数时,例如
n = 1
):
# 422 Error: Unprocessable Entity
{
"detail": [
{
"loc": [
"n"
],
"msg": "Input number is not even",
"type": "value_error"
}
],
"custom msg": [
"Your error message"
]
}
请注意,在 Pydantic V2 中,
@validator
已被弃用,并被 @field_validator
取代。请查看此答案以获取更多详细信息和示例。