1. 程式人生 > 其它 >FastAPI(10)- 詳解 Body

FastAPI(10)- 詳解 Body

FastAPI(10)- 詳解 Body

前言

  • 上一篇有講到將引數型別指定為 Pydantic Model,這樣 FastAPI 會解析它為一個 Request Body
  • 那單型別(int、float、str、bool...)引數可以成為 Request Body 的一部分嗎?答案是可以的
  • 通過 Body 函式即可完成,和 Path、Query 有異曲同工之妙

文章跳轉

Query

Path

Request Body

Body

  • 主要作用:可以將單型別的引數成為 Request Body 的一部分,即從查詢引數變成請求體引數
  • 和 Query、Path 提供的額外校驗、元資料是基本一致的(多了個 embed 引數,最後講解)

Body 的簡單栗子

from typing import Optional

import uvicorn
from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
full_name: Optional[str] = None @app.put("/items/{item_id}") async def update_item( item_id: int, item: Item, user: User, importance: int = Body(...) ): results = {"item_id": item_id, "item": item, "user": user, "importance": importance} return results if
__name__ == "__main__": uvicorn.run(app="8_Body:app", host="127.0.0.1", port=8080, reload=True, debug=True)

期望得到的 Request Body

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}

Request Body 中多了個 importance

正確傳參的請求結果

檢視 Swagger API 文件

Query、Path、Body 終極混用

from typing import Optional

import uvicorn
from fastapi import Body, FastAPI, Path, Query
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
    full_name: Optional[str] = None


@app.put("/item_all/{item_id}")
async def update_item(
        *,
        item_id: int = Path(default=..., description="路徑引數", gt=0, lt=10),
        address: str = Query(default=None, description="查詢引數", max_length=10),
        item: Item,
        user: User,
        importance: int = Body(default=..., description="請求體", ge=1, le=5)
):
    results = {
        "item_id": item_id,
        "address": address,
        "item": item,
        "user": user,
        "importance": importance
    }
    return results

正確傳參的請求結果

檢視 Swagger API 文件

Body() 中的 embed 引數

為什麼要講這個 embed 引數

當函式只有一個引數指定了 Pydantic Model 且沒有其他 Body 引數時,傳參的時候請求體可以不指定引數名

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


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

期望得到的請求體

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}

預設並不需要指定 item 為欄位名

那假設想指定 item 為請求體的欄位名呢?就是通過 embed 引數達到目的了

實際程式碼

from typing import Optional

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(
        *,
        item_id: int,
        # 將 embed 設定為 True
        item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

期望得到的請求體

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    }
}

正確傳參的請求結果

還是不傳 item 欄位的請求結果

檢視 Swagger API 文件