当前位置: 首页 > article >正文

Python FastApi(5):请求体、查询参数和字符串校验

1 请求体

        FastAPI 使用请求体从客户端(例如浏览器)向 API 发送数据。请求体是客户端发送给 API 的数据。响应体是 API 发送给客户端的数据。API 基本上肯定要发送响应体,但是客户端不一定发送请求体。使用 Pydantic 模型声明请求体,能充分利用它的功能和优点。

1.1 使用Pydantic 的 BaseModel

        从 pydantic 中导入 BaseModel

from fastapi import FastAPI
from pydantic import BaseModel

        把数据模型声明为继承 BaseModel 的类。使用 Python 标准类型声明所有属性:

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

        与声明查询参数一样,包含默认值的模型属性是可选的,否则就是必选的。默认值为 None 的模型属性也是可选的。例如,上述模型声明如下 JSON 对象(即 Python 字典):

{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}

        由于 description 和 tax 是可选的(默认值为 None),下面的 JSON 对象也有效:

{
    "name": "Foo",
    "price": 45.2
}

        使用与声明路径和查询参数相同的方式声明请求体,把请求体添加至路径操作。此处,请求体参数的类型为 Item 模型。

@app.post("/items/")
async def create_item(item: Item):
    return item

        仅使用 Python 类型声明,FastAPI 就可以:

  • 以 JSON 形式读取请求体
  • (在必要时)把请求体转换为对应的类型
  • 校验数据:
    • 数据无效时返回错误信息,并指出错误数据的确切位置和内容
  • 把接收的数据赋值给参数 item
    • 把函数中请求体参数的类型声明为 Item,还能获得代码补全等编辑器支持
  • 为模型生成 JSON Schema,在项目中所需的位置使用
  • 这些概图是 OpenAPI 概图的部件,用于 API 文档 UI

1.2 API 文档

        Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文档中显示:

1.3 使用模型

        在路径操作函数内部直接访问模型对象的属性:

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.dict()
    if item.tax is not None:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

1.4 请求体 + 路径参数

        FastAPI 支持同时声明路径参数和请求体。FastAPI 能识别与路径参数匹配的函数参数,还能识别从请求体中获取的类型为 Pydantic 模型的函数参数。

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


app = FastAPI()


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {"item_id": item_id, **item.dict()}

1.5 请求体 + 路径参数 + 查询参数

        FastAPI 支持同时声明请求体路径参数查询参数FastAPI 能够正确识别这三种参数,并从正确的位置获取数据。

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


app = FastAPI()


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None = None):
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result

        函数参数按如下规则进行识别:

  • 路径中声明了相同参数的参数,是路径参数
  • 类型是(intfloatstrbool 等)单类型的参数,是查询参数
  • 类型是 Pydantic 模型的参数,是请求体

2 查询参数和字符串校验

        FastAPI 允许你为参数声明额外的信息和校验。让我们以下面的应用程序为例:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/")
async def read_items(q: str | None = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

2.1 Query使用

        查询参数 q 的类型为 str,默认值为 None,因此它是可选的。我们打算添加约束条件:即使 q 是可选的,但只要提供了该参数,则该参数值不能超过50个字符的长度。为此,首先从 fastapi 导入 Query

from typing import Union
from fastapi import FastAPI, Query

        现在,将 Query 用作查询参数的默认值,并将它的 max_length 参数设置为 50:

@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

        由于我们必须用 Query(default=None) 替换默认值 NoneQuery 的第一个参数同样也是用于定义默认值。

q: Union[str, None] = Query(default=None)

        然后,我们可以将更多的参数传递给 Query。在本例中,适用于字符串的 max_length 参数,将会校验数据,在数据无效时展示清晰的错误信息,并在 OpenAPI 模式的路径操作中记录该参​​数。

        你还可以更多校验:

# 最小值校验
q: Union[str, None] = Query(default=None, min_length=3, max_length=50)

# 正则表达式
q: Union[str, None] = Query(
        default=None, min_length=3, max_length=50, pattern="^fixedquery$"
    )

2.2 默认值和必需参数

        你可以向 Query 的第一个参数传入 None 用作查询参数的默认值,以同样的方式你也可以传递其他默认值。假设你想要声明查询参数 q,使其 min_length 为 3,并且默认值为 fixedquery,具有默认值还会使该参数成为可选参数。

q: str = Query(default="fixedquery", min_length=3)

        当我们不需要声明额外的校验或元数据时,只需不声明默认值就可以使 q 参数成为必需参数,例如:

q: str = Query(min_length=3)

        你可以声明一个参数可以接收None值,但它仍然是必需的。这将强制客户端发送一个值,即使该值是None。为此,你可以声明None是一个有效的类型,并仍然使用default

q: Union[str, None] = Query(min_length=3)

2.3 查询参数列表

        当你使用 Query 显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。例如,要声明一个可在 URL 中出现多次的查询参数 q,你可以这样写:

from typing import List, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

        然后,输入如下网址:

http://localhost:8000/items/?q=foo&q=bar

        你会在路径操作函数函数参数 q 中以一个 Python list 的形式接收到查询参数 q 的多个值(foo 和 bar)。因此,该 URL 的响应将会是:

{
  "q": [
    "foo",
    "bar"
  ]
}

        要声明类型为 list 的查询参数,如上例所示,你需要显式地使用 Query,否则该参数将被解释为请求体。交互式 API 文档将会相应地进行更新,以允许使用多个值:

        还可以定义在没有任何给定值时的默认 list 值:

q: List[str] = Query(default=["foo", "bar"])

        如果访问:

http://localhost:8000/items/

  q 的默认值将为:["foo", "bar"],你的响应会是:

{
  "q": [
    "foo",
    "bar"
  ]
}

        你也可以直接使用 list 代替 List [str]

q: list = Query(default=[])

        请记住,在这种情况下 FastAPI 将不会检查列表的内容。例如,List[int] 将检查(并记录到文档)列表的内容必须是整数。但是单独的 list 不会。

2.4 声明更多元数据

        你可以添加更多有关该参数的信息。这些信息将包含在生成的 OpenAPI 模式中,并由文档用户界面和外部工具所使用。你可以添加 title以及description

q: Union[str, None] = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    )

2.5 别名参数

        假设你想要查询参数为 item-query。像下面这样:

http://127.0.0.1:8000/items/?item-query=foobaritems

        但是 item-query 不是一个有效的 Python 变量名称。最接近的有效名称是 item_query。但是你仍然要求它在 URL 中必须是 item-query。这时你可以用 alias 参数声明一个别名,该别名将用于在 URL 中查找查询参数值:

q: Union[str, None] = Query(default=None, alias="item-query"

2.6 弃用参数

        现在假设你不再喜欢此参数。你不得不将其保留一段时间,因为有些客户端正在使用它,但你希望文档清楚地将其展示为已弃用。那么将参数 deprecated=True 传入 Query

q: Union[str, None] = Query(
        default=None,
        alias="item-query",
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
        max_length=50,
        pattern="^fixedquery$",
        deprecated=True,
    )

        文档将会像下面这样展示它:


http://www.kler.cn/a/601053.html

相关文章:

  • k8s存储介绍(四)hostpath
  • 智能汽车图像及视频处理方案,支持视频实时拍摄特效能力
  • uv - pip 接口
  • 【多媒体交互】Unity+普通摄像头实现UI事件分析
  • VUE项目初始化
  • MATLAB 绘制空间分布图 方法总结
  • 【MySQL】mysql日志文件
  • 【QT】Qlcdnumber的使用
  • openai-agents-python中 agents_as_tools.py 示例
  • vue-如何将组件内容作为图片生成-html2canvas
  • Android ADB工具使用教程(从安装到使用)
  • 代理记账的第三个十年
  • Matlab多种算法解决未来杯B的多分类问题
  • 处理json,将接口返回的数据转成list<T>,和几个时间处理方法的工具类
  • 【杂记四】刚体运动 +SE(3)
  • Linux 安装 Redis
  • 【AI】NLP
  • 生活电子常识——浏览器解决DNS劫持,避免自动跳转非法网站
  • 2025.3.25总结
  • SPPAS安装及问题汇总