fastapi-参数

路径参数

你可以使用与 Python 格式化字符串相同的语法来声明路径"参数"或"变量":

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def item_details(item_id: int):
    return {"item_id": item_id}

路径参数item_id的值将作为参数item_id传递给你的函数。在Swagger UI中的表现如下:

fastapi-参数_第1张图片

然后,我们可以访问http://127.0.0.1:8000/items/1,将会看到如下响应:

{
    "item_id": 1
}

另外,fastapi还具有一个数据校验的功能,如果你通过浏览器访问http://127.0.0.1:8000/items/foo,你会看到一个清晰可读的422 HTTP错误,如下:

{
    "detail": [
        {
            "loc": [
                "path",
                "item_id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}

因为路径参数item_id传入的值为 “foo”,它不是一个int,如果你提供的是float而非整数也会出现同样的错误!

假设,有如下例子:


@app.get("/items/me")
async def items_me():
    pass
    
@app.get("/items/{user_id}")
async def items_details(user_id):
    pass

当我们访问http://127.0.0.1:8000/items/me时,我们会发生永远都是走的第一个路由,这是因为路由操作是按顺序依次运行的。如果将@app.route("/items/{user_id}")写在前面,那么/items/{user_id}的路径还将与/items/me相匹配,认为自己正在接收一个值为“me”的user_id参数!

fastapi还支持使用Enum来创建具有固定值的类属性参数,如下:

from enum import Enum
from fastapi import FastAPI

app = FastAPI()

class EnumParams(str, Enum):
    Man = "man"
    Woman = "woman"

@app.get("/people/{sex}")
async def people(sex: EnumParams):
    return {"sex": sex}

当传递的位置参数不是EnumParams设置的值时,将会校验不通过!

假设你有一个路径操作,它的路径为/files/{file_path},但是你需要file_path自身也包含路径,比如/home/johndoe/myfile.txt。因此,该文件的URL将类似于这样:/files/home/johndoe/myfile.txt

@app.get("/files/{path}")
async def people(path: str):
    return {"path": path}

当我们访问localhost:8000/files/home/johndoe/myfile.txt时,并不能如愿,而是返回了一个错误!这是因为不支持任何方式去声明路径参数以在其内部包含路径,因为这可能会导致难以测试和定义的情况出现。

不过,我们仍可以使用其他方式来实现它,如下:

@app.get("/files/{path: path}")
async def people(path: str):
    return {"path": path}

当校验url非为path时,且没有其他路由与之匹配,那么将会返回404错误!

除了path关键字之外,其他常用的定义类型的关键字如下:

  • str: 表示参数为字符串
  • int: 表示参数为整型数字
  • float: 表示参数为浮点型数字
  • uuid: 表示参数为uuid

除了这些常用的关键字之外,我们还可以进行自定义。使用如下:

from fastapi import FastAPI
from starlette.convertors import Convertor
from starlette.convertors import register_url_convertor

class CustomConvertor(Convertor):
    regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"

    def convert(self, value: str) -> str:
        return str(value)

    def to_string(self, value: str) -> str:
        return str(value)

app = FastAPI()
register_url_convertor('custom', CustomConvertor())

@app.get("/items/{item_id:custom}")
async def item_details(item_id: str):
    return {"item_id": item_id}

值得注意的是,在方法中定义的参数类型,需要与Convertorconvert方法返回的类型一致,否则将会引发422错误!!!

查询参数

声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数

from fastapi import FastAPI

app = FastAPI()
data = [{"name": "zhangsan", "age": 1}, {"name": "lisi", "age": 2}]

@app.get("/people")
async def people(offset: int, limit: int):
    return data[offset: offset+limit]

在Swagger UI中的表现形式如下:

fastapi-参数_第2张图片

查询字符串是键值对的集合,这些键值对位于URL?之后,并以&符号分隔。当我们访问http://localhost:8000/people?offset=0&limit=1时,则会将offset与limit传递到对应的参数里边!

另外还可以对参数设置默认值,如下:

@app.get("/people")
async def people(offset: int, limit: int = 20):
    return data[offset: offset+limit]

则当请求的url中未携带limit参数时,将默认为limit为20!

此外,我们还可以声明bool类型的参数,他们将被自动转换,如下:

@app.get("/people")
async def people(is_woman: bool):
    return {"woman": is_woman}

当我们访问如下url时,都将会把参数的值自动转换为True

http://localhost:8000/people?is_woman=1
http://localhost:8000/people?is_woman=True
http://localhost:8000/people?is_woman=true
http://localhost:8000/people?is_woman=yes
http://localhost:8000/people?is_woman=on

当路径参数和查询参数同时存在时,如下:

@app.get("/people/{id}")
async def people(id: int, is_woman: bool):
    return {"woman": is_woman}

可同时存在多个路径参数和查询参数,并且不需要以任何特定的顺序来声明!

有的时候,我们可能会需要接收一个List的数据,就像这样:http://localhost:8000/users?id=1&id=2,在FastAPI中,我们可以这么定义,如下:

@app.get("/users")
async def user_list(id: List[int]):
    pass

请求体参数

当你需要将数据从客户端(例如浏览器)发送给API时,你将其作为「请求体」发送。请求体是客户端发送给API的数据。响应体是API发送给客户端的数据。你的API几乎总是要发送响应体。但是客户端并不总是需要发送请求体。我们使用Pydantic模型来声明请求体,并能够获得它们所具有的所有能力和优点。安装如下:

pip install pydantic

然后在对其进行导入,使用如下:

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str|None = None
    price: float
    tax: float|None = None
    
@app.post("/items/")
async def create_item(item: Item):
    return item

在Swagger UI中的表现形式如下:

fastapi-参数_第3张图片

你可能感兴趣的:(fastapi,fastapi,python)