一、FastAPI中的参数

在 FastAPI 中,参数就是客户端发送给服务器的数据,这些数据会被 FastAPI 自动解析并传递给函数中的变量。因此,对于同一段接口逻辑,参数不同返回的数据不同。

FastAPI 中3种常见的参数来源
类型来源示例
路径参数URL路径/book/{id}
查询参数URL ? 后面/book?id=1
请求体body JSONPOST数据

二、路径参数

0、啥是路径参数?

路径参数(Path Parameter)出现在URL里。在 URL 路径中使用 {} 占位的部分就是路径参数。

示例代码:

@app.get("/book/{id}")    # "/book/{id}" 中的 id 就是路径参数。
async def get_book(id):   # 此处的get_book函数的参数id就是上一行的路径参数id

第二行代码的函数参数 id 就是第一行的路径参数 id,这是FastAPI的规则。只要函数参数路径参数同名两者就会自动绑定


在实际业务中,通常会对路径参数设置一些条件或限制,比如 book id 一般都是数字组成,那就需要使用类型注解对路径参数的类型、长度等方面进行限制或说明。

1、Python原生类型注解

当我们想让书籍 id 为整型时,可以用 Python 的原生注解限制路径参数 id 的类型:

@app.get("/book/{id}")
async def get_book(id: int):                    #Python原生注解可以把id框定为int类型
    return {"id": id, "title": f"这是第{id}本书}

根据不同场景的需求,可以把 id 框定为其他类型,如 str 类型:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/usr/{id}")
async def practice(id: str):            # 把id框定为str类型
    return {"usr_id": id, "名称": f"普通用户 {id}"}

2、Path 类型注解

除了约束路径参数的类型,fastapi 包中的 Path 函数为参数声明额外的信息和校验。

Path 可以实现路径参数在长度和范围等方面的约束,Path的常用参数有:

Path常用参数
Path参数说明
...表示参数为必填项,一般路径参数都是必填项
gt/ge大于/大于等于
lt/le

小于/小于等于

description描述
min_length/max_length长度限制

下面利用代码详细说明Path的用法:

#导入Path
from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "hello world"}

@app.get("/book/{id}")
#使用Path限制id的取值边界为1——100
async def practice(id: int = Path(..., gt = 0, lt = 101)):    # ...表示id这个参数是必填项
    return {"book id": id}

除此之外,Path还可以为函数参数起别名,适用于不方便修改函数参数名,且函数参数路径参数指代一致但名称不一致的情况。比如,函数中指代book id的参数名必须为 b_id,但是指代 book id 的路径参数叫 id,可以使用 Path( ..., alias = "id") 指定映射关系,让 b_id 和 id 互为别名:

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "hello world"}

@app.get("/book/{id}")
async def practice(b_id: int = Path(..., gt = 0, lt = 101, alias = "id")):
    return {"book id": b_id}

三、查询参数

0、啥是查询参数?

在 FastAPI 中,不出现在 URL 路径中的函数参数通常会被解析为查询参数,且可以设置默认值。查询参数以键值对形式出现在 URL 的 ? 后,例如:/book?id=1&page=2,多个查询参数用 & 符号连接。查询参数的作用是对请求进行筛选、排序或分页等附加条件控制。

1、Python原生类型注解

对于查询参数,可以用 Python 原生类型注解对其进行类型说明并且添加默认值。代码示例:

@app.get("/book")
async def practice(name: str = "OneBook", id: int = 2):    # 对id进行类型说明并且添加默认值1
    return {"id": id, "name": name}

注意:Python 参数定义的规则(核心)函数参数书写必须遵循这个顺序:先写完无默认值参数 ,再写有默认值参数。async def practice(id: int = 1, name: str): 这样的写法会报错。

运行上述代码可以在 /docs 里执行后看到构造出的URL:

2、Query类型注解

对于查询参数,如果需要对其添加额外的限制,可以用 fastapi 中的 Query 函数实现更加详细的注解。Query 函数中的常用参数跟 Path 高度一致:

Query常用参数
Path参数说明
...表示参数为必填项,若设置了默认值,则参数为选填项
gt/ge大于/大于等于
lt/le

小于/小于等于

description描述

min_length

/max_length

长度限制

代码示例:

from fastapi import FastAPI, Query

@app.get()
async def get_news_list(
    skip: int = Query(0, description = "跳过的记录数", lt = 101),    # 0被设置为skip的默认值,skip为选填项,下面的limit同理
    limit: int = Query(10, description = "返回的记录数")
    ):

四、请求体参数

0、啥是请求体参数?

在 HTTP 协议中,一个完整的请求由 请求行、请求头和请求体 三部分组成。请求体参数就是通过 HTTP 请求的请求体(通常是 JSON 格式)传递给服务器的数据。它的作用是向服务器提交结构化数据,例如在创建或更新资源时使用。例如,用户在浏览器中注册账号时,用户名和密码通常就会作为请求体参数发送到服务器。

在代码层面,当函数参数的类型是 BaseModel(或其子类) 时,FastAPI 会自动将其识别为请求体参数。因此,在使用请求体参数时,需要引入 pydantic 中的 BaseModel(可以理解为一个“数据模板 + 校验器”)来定义数据结构。

1、python原生类型注解

用代码实现用户向服务器POST账号和密码:

from fastapi import FastAPI
from pydantic import BaseModel    # 引入BaseModel,它用于定义请求数据的结构(数据长什么样),并自动对数据进行校验(数据对不对)。

app = FastAPI()
class User(BaseModel):            # 定义User类,User继承BaseModel
    username: str
    password: str

...

@app.post("/register")            # 提交信息时一般采用post方法
async def register(user: User):   # user的类型是BaseModel的子类时,user就是一个请求体参数
    return user

可以看到对于请求体参数 user 用了Python原生类型注解,把 user 注解为 User 类型(User 是 BaseModel 的子类)。

代码运行效果如下:

2、Field类型注解

当Python原生类型注解不够用的时候,就需要 Field 来对请求体参数做出额外的注解。

Field是Pydantic模块里面的一个方法,使用前需要用 from pydantic import Field 来导入。Field常用的参数跟Path和Query差不多:

Field常用参数
...表示参数为必填项,若设置了默认值,则参数为选填项
gt/lt大于/小于
ge/le大于等于/小于等于
default默认值
description描述

min_length

/max_length

长度限制

用一段代码来说明Field的用法:

from fastapi import FastAPI
from pydantic import BaseModel, Field    # 导入Field

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "hello world"}

class NewBook(BaseModel):
    bookname: str = Field(default = "一本书", min_length=2, max_length=10)    # 对bookname进行注解
    author: str
    publisher: str
    price: int

@app.post("/add/book")
async def add_book(newbook: NewBook):
    return newbook

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐