路径参数

函数参数中出现在路径操作装饰器中,该参数称为路径参数

  1. app = FastAPI()
  2. @app.get("/info/{id}")
  3. async def info(id: str):
  4. return {
  5. "id": id
  6. }
  7. # 以上参数id称为路径参数

路径参数更多校验-Path

导入Path可为路径参数声明元数据和校验

  1. from fastapi import FastAPI, Path
  2. """路径参数校验Path"""
  3. # 声明元数据
  4. @app.get("/items/{item_id}/{id}")
  5. def read_item(
  6. item_id: str = Path(..., title="这是元数据title", description="这是描述", max_length=10),
  7. id: int = Path(..., ge=0, le=10)
  8. ):
  9. return {"item_id": item_id}

查询参数

函数参数中没有出现在路径操作装饰器中的参数,称为查询参数

  1. @app.get("/info_1")
  2. async def info_1(id: str):
  3. return {
  4. "id": id
  5. }
  6. """
  7. curl --location --request GET 'http://127.0.0.1:8087/info_1?id=1' \
  8. --data-raw ''
  9. {
  10. "id": "1"
  11. }
  12. """
  13. # 以上参数id为查询参数

查询参数更多校验-Query

设置默认值

  1. from fastapi import FastAPI, Query
  2. # 设置默认值
  3. @app.get('/read_items')
  4. # 设置q参数默认值为test
  5. async def read_items(q: Optional[str] = Query("test", max_length=50)):
  6. results = {"item_id": "12345"}
  7. if q:
  8. results.update({"q": q})
  9. print("results:", results)
  10. return results

声明是否必填参数

通过Query显性的声明一个值是否必填,可通过…作为第一个参数值

  1. # 声明参数必填
  2. @app.get("/read_items")
  3. async def read_items(q: str = Query(..., max_length=30)):
  4. return {"q": q}
  5. """
  6. q参数不填时提示信息如下:
  7. {
  8. "detail": [
  9. {
  10. "loc": [
  11. "query",
  12. "q"
  13. ],
  14. "msg": "field required",
  15. "type": "value_error.missing"
  16. }
  17. ]
  18. }
  19. """

设置参数限制

min_length:限制参数最小字符长度 max_length:限制参数最大字符长度 regex:参数匹配正则表达式

  1. # 参数限制
  2. @app.get("/read_items")
  3. async def read_items(
  4. q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$")
  5. ):
  6. return {"q": q}

声明参数元数据

title:参数标题 description:参数描述

  1. # 添加参数元数据
  2. @app.get("/read_items")
  3. async def read_items(
  4. q: Optional[str] = Query(
  5. None,
  6. title="请求参数title",
  7. description="请求参数描述文本",
  8. min_length=3,
  9. )
  10. ):
  11. return {"q": q}

image.png

别名参数&弃用参数

有时候查询参数为item-id,但是该参数在python是非法的,这时候可以用上alias声明一个别名

  1. # 设置参数别名
  2. @app.get("/read_items/")
  3. async def read_items(q: str = Query(None, alias="item-id")):
  4. return {"q": q}
  5. """
  6. 请求URL:http://127.0.0.1:8087/read_items?item-id=zaygee
  7. """

请求体

pydantic模型请求体&查询参数&路径参数

pydantic模型使用

  • item.dict():返回模型字段和值的字典
  • **item.dict(): 字典解包 ```python class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None

@app.put(“/items/{item_id}”) async def create_item(item_id: int, item: Item, q: Optional[str] = None):

  1. # {'name': 'zayee', 'description': 'dddfsdfdsf', 'price': 10.0, 'tax': 110.0} <class 'dict'> zayee
  2. print(item.dict(), type(item.dict()), item.dict().get("name", ""))
  3. # result: {'item_id': 3243, 'name': 'zayee', 'description': 'dddfsdfdsf', 'price': 10.0, 'tax': 110.0}
  4. result = {"item_id": item_id, **item.dict()}
  5. ...
  1. <a name="lRUtC"></a>
  2. #### 多个参数中的单一参数-Body
  3. > 导入Body,可起到扩充已定义模型的作用
  4. ```python
  5. from fastapi import Body
  6. class Item(BaseModel):
  7. name: str
  8. description: Optional[str] = None
  9. price: float
  10. tax: Optional[float] = None
  11. class User(BaseModel):
  12. username: str
  13. full_name: Optional[str] = None
  14. @app.put("/items/{item_id}")
  15. async def update_item(
  16. item_id: int, item: Item, user: User, importance: int = Body(...)
  17. ):
  18. results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
  19. return results
  20. @app.post("/items_2")
  21. async def get_item(
  22. item_id: int, data: str = Body(...), items: str= Body(...)
  23. ):
  24. return {"item_id": item_id, "data": data, "items": items}

嵌入单个请求体参数-embed=True

如果你希望item键的值为包含模型的json,可以设置Body的参数embed=True

  1. """嵌入单个请求体参数
  2. request:
  3. {
  4. "items": {
  5. "name": "string",
  6. "description": "string",
  7. "price": 0,
  8. "tax": 0
  9. }
  10. }
  11. """
  12. @app.post("/items_3")
  13. async def get_item_2(
  14. items: Item = Body(..., embed=True)
  15. ):
  16. return {"items": items}

pydantic模型增加元数据&属性校验-Field

  1. from pydantic import Field
  2. """pydantic模型声明元数据&校验 -- Field"""
  3. class ItemField(BaseModel):
  4. name: str = Field("zaygee", title="名称", description="这是描述", max_length=100)
  5. description: Optional[str] = None
  6. price: float = Field(..., ge=0.0, le=100.0)
  7. tax: Optional[float] = None
  8. @app.post("/items-4")
  9. async def get_items_4(items: ItemField):
  10. return {"items": items}

多层嵌套模型

  1. class Image(BaseModel):
  2. url: HttpUrl
  3. name: str
  4. class Item5(BaseModel):
  5. name: str
  6. description: Optional[str] = None
  7. price: float
  8. tax: Optional[float] = None
  9. tags: Set[str] = set()
  10. images: Optional[List[Image]] = None
  11. @app.put("/items5/{item_id}")
  12. async def update_item(item_id: int, item: Item5):
  13. results = {"item_id": item_id, "item": item}
  14. return results
  15. """
  16. {
  17. "name": "string",
  18. "description": "string",
  19. "price": 0,
  20. "tax": 0,
  21. "tags": [],
  22. "images": [
  23. {
  24. "url": "string",
  25. "name": "string"
  26. }
  27. ]
  28. }
  29. """

接收表单数据

接收的不是json,而是表单字段,要使用Form
条件: 安装python-multipart包

  1. from fastapi import Form
  2. """表单数据-Form"""
  3. @app.post("/item12")
  4. async def item12(username: str = Form(...), pw: str= Form(...)):
  5. return {"username": username}

为参数&请求体添加示例

针对请求体或者请求参数为接口在接口文档中添加请求示例

pydantic 的schema_extra

  1. class Item(BaseModel):
  2. name: str
  3. description: Optional[str] = None
  4. price: float
  5. tax: Optional[float] = None
  6. class Config:
  7. schema_extra = {
  8. "example": {
  9. "name": "Foo",
  10. "description": "A very nice Item",
  11. "price": 35.4,
  12. "tax": 3.2,
  13. }
  14. }
  15. @app.put("/items/{item_id}")
  16. async def update_item(item_id: int, item: Item):
  17. results = {"item_id": item_id, "item": item}
  18. return results

Field

  1. class Item(BaseModel):
  2. name: str = Field(..., example="Foo")
  3. description: Optional[str] = Field(None, example="A very nice Item")
  4. price: float = Field(..., example=35.4)
  5. tax: Optional[float] = Field(None, example=3.2)

Body

  1. @app.put("/items/{item_id}")
  2. async def update_item(
  3. item_id: int,
  4. item: Item = Body(
  5. ...,
  6. example={
  7. "name": "Foo",
  8. "description": "A very nice Item",
  9. "price": 35.4,
  10. "tax": 3.2,
  11. },
  12. ),
  13. ):
  14. results = {"item_id": item_id, "item": item}
  15. return results

Cookie 参数 && Header参数

设置Header参数时,可通过设置convert_underscores=False,来禁止下划线的自动转换

  1. from fastapi import Cookie, Header
  2. @app.get("/items8")
  3. async def get_items8(
  4. asd_id: Optional[str] = Cookie(None),
  5. user_agent: Optional[str] = Header(None, convert_underscores=True)
  6. ):
  7. """声明Cookie 参数 && Header参数
  8. """
  9. return "声明Cookie 参数 && Header参数"

总结

  • 如果在路径中也声明了该参数,它将被用作路径参数。
  • 如果参数属于单一类型(比如 int、float、str、bool 等)它将被解释为查询参数。
  • 如果参数的类型被声明为一个 Pydantic 模型,它将被解释为请求体