Skip to content

額外的資料型別

🌐 AI 與人類共同完成的翻譯

此翻譯由人類指導的 AI 完成。🤝

可能會有對原意的誤解,或讀起來不自然等問題。🤖

你可以透過協助我們更好地引導 AI LLM來改進此翻譯。

英文版

到目前為止,你一直在使用常見的資料型別,例如:

  • int
  • float
  • str
  • bool

但你也可以使用更複雜的資料型別。

而且你仍然會擁有目前為止所見的同樣功能:

  • 極佳的編輯器支援。
  • 將傳入請求的資料轉換。
  • 回應資料的轉換。
  • 資料驗證。
  • 自動產生註解與文件。

其他資料型別

以下是你可以使用的一些其他資料型別:

  • UUID
    • 一種標準的「通用唯一識別碼 (Universally Unique Identifier)」,常見於許多資料庫與系統的 ID。
    • 在請求與回應中會以 str 表示。
  • datetime.datetime
    • Python 的 datetime.datetime
    • 在請求與回應中會以 ISO 8601 格式的 str 表示,例如:2008-09-15T15:53:00+05:00
  • datetime.date
    • Python 的 datetime.date
    • 在請求與回應中會以 ISO 8601 格式的 str 表示,例如:2008-09-15
  • datetime.time
    • Python 的 datetime.time
    • 在請求與回應中會以 ISO 8601 格式的 str 表示,例如:14:23:55.003
  • datetime.timedelta
    • Python 的 datetime.timedelta
    • 在請求與回應中會以總秒數的 float 表示。
    • Pydantic 也允許用「ISO 8601 time diff encoding」來表示,詳情見文件
  • frozenset
    • 在請求與回應中與 set 相同處理:
      • 在請求中,會讀取一個 list,去除重複並轉為 set
      • 在回應中,set 會被轉為 list
      • 生成的 schema 會指定 set 的值為唯一(使用 JSON Schema 的 uniqueItems)。
  • bytes
    • 標準的 Python bytes
    • 在請求與回應中會被當作 str 處理。
    • 生成的 schema 會指定其為 str,且 "format" 為 binary
  • Decimal
    • 標準的 Python Decimal
    • 在請求與回應中,與 float 的處理方式相同。
  • 你可以在此查閱所有可用的 Pydantic 資料型別:Pydantic 資料型別

範例

以下是一個帶有參數、使用上述部分型別的 路徑操作 (path operation) 範例。

from datetime import datetime, time, timedelta
from typing import Annotated
from uuid import UUID

from fastapi import Body, FastAPI

app = FastAPI()


@app.put("/items/{item_id}")
async def read_items(
    item_id: UUID,
    start_datetime: Annotated[datetime, Body()],
    end_datetime: Annotated[datetime, Body()],
    process_after: Annotated[timedelta, Body()],
    repeat_at: Annotated[time | None, Body()] = None,
):
    start_process = start_datetime + process_after
    duration = end_datetime - start_process
    return {
        "item_id": item_id,
        "start_datetime": start_datetime,
        "end_datetime": end_datetime,
        "process_after": process_after,
        "repeat_at": repeat_at,
        "start_process": start_process,
        "duration": duration,
    }
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from datetime import datetime, time, timedelta
from uuid import UUID

from fastapi import Body, FastAPI

app = FastAPI()


@app.put("/items/{item_id}")
async def read_items(
    item_id: UUID,
    start_datetime: datetime = Body(),
    end_datetime: datetime = Body(),
    process_after: timedelta = Body(),
    repeat_at: time | None = Body(default=None),
):
    start_process = start_datetime + process_after
    duration = end_datetime - start_process
    return {
        "item_id": item_id,
        "start_datetime": start_datetime,
        "end_datetime": end_datetime,
        "process_after": process_after,
        "repeat_at": repeat_at,
        "start_process": start_process,
        "duration": duration,
    }

請注意,函式內的參數會是它們的自然資料型別,因此你可以進行一般的日期運算,例如:

from datetime import datetime, time, timedelta
from typing import Annotated
from uuid import UUID

from fastapi import Body, FastAPI

app = FastAPI()


@app.put("/items/{item_id}")
async def read_items(
    item_id: UUID,
    start_datetime: Annotated[datetime, Body()],
    end_datetime: Annotated[datetime, Body()],
    process_after: Annotated[timedelta, Body()],
    repeat_at: Annotated[time | None, Body()] = None,
):
    start_process = start_datetime + process_after
    duration = end_datetime - start_process
    return {
        "item_id": item_id,
        "start_datetime": start_datetime,
        "end_datetime": end_datetime,
        "process_after": process_after,
        "repeat_at": repeat_at,
        "start_process": start_process,
        "duration": duration,
    }
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

from datetime import datetime, time, timedelta
from uuid import UUID

from fastapi import Body, FastAPI

app = FastAPI()


@app.put("/items/{item_id}")
async def read_items(
    item_id: UUID,
    start_datetime: datetime = Body(),
    end_datetime: datetime = Body(),
    process_after: timedelta = Body(),
    repeat_at: time | None = Body(default=None),
):
    start_process = start_datetime + process_after
    duration = end_datetime - start_process
    return {
        "item_id": item_id,
        "start_datetime": start_datetime,
        "end_datetime": end_datetime,
        "process_after": process_after,
        "repeat_at": repeat_at,
        "start_process": start_process,
        "duration": duration,
    }