处理fastapi出现报错HTTPException(status_code=422, detail=e.errors())
报错的原因
HTTPException(status_code=422, detail=e.errors()) 在 Python 中使用 FastAPI 时表示请求参数验证失败。 status_code=422 是 HTTP 状态码,表示请求格式正确,但是由于语义错误无法处理。detail=e.errors() 表示验证错误的详细信息。
如何解决
可以通过对请求参数进行验证来解决这个问题。FastAPI提供了一组内置验证器,例如 `min_length`, `max_length`, `range` 等,以及 Pydantic 模型来验证请求参数。例如,使用 Pydantic 模型定义请求参数并使用 @validate_query 标记要验证的参数。
例如:
from fastapi import FastAPI, Query, HTTPException
from pydantic import BaseModel, validator
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@validator("price")
def price_must_be_positive(cls, value):
if value <= 0:
raise ValueError("Price must be greater than zero.")
return value
@app.get("/items/{item_id}")
def read_item(item_id: int, item: Item = Query(None, alias="item", title="The item to get", description="Item description")):
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item
在这个例子中,我们用Pydantic模型定义了一个Item,并使用validator装饰器来验证它的price字段,如果price<=0 那么就抛出异常。
还可以自定义验证函数,使用`@app.query_param()`或`@app.path_param()`装饰器来验证请求参数。
另外,当验证失败时,可以使用 `raise HTTPException(status_code=422, detail="Validation Error: {error_msg}")` 或者 `raise HTTPException(status_code=422, detail=e.errors())` 来返回验证错误。
使用例子
当然,下面是使用 `@app.query_param()` 装饰器来验证请求参数的例子:
from fastapi import FastAPI, Query, HTTPException
app = FastAPI()
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 100):
if limit > 100:
raise HTTPException(
status_code=400,
detail="limit should be less than or equal to 100"
)
return {"skip": skip, "limit": limit}
这个例子中,我们定义了两个请求参数 `skip` 和 `limit` ,并使用了 `if` 语句来验证它们。如果 limit > 100,则会抛出一个 HTTPException 异常,并返回一个 HTTP 状态码 400 和一条错误信息 "limit should be less than or equal to 100"。
也可以自定义验证函数,并使用装饰器来验证请求参数
from fastapi import FastAPI, Query, HTTPException
app = FastAPI()
def is_valid_limit(value: int):
if value > 100:
raise ValueError("limit should be less than or equal to 100")
return value
@app.get("/items/")
def read_items(skip: int = 0, limit: int = Query(100, gt=0, lt=100)):
return {"skip": skip, "limit": limit}
这里我们定义了一个自定义验证函数is_valid_limit,并使用了`@app.query_param(validate=is_valid_limit)` 来验证请求参数 limit。
还可以通过使用第三方库来进行验证,例如:`marshmallow`, `cerberus`等。