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 文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM