fastapi個人學習記錄

TsayDust發表於2024-07-11

FastAPI快速入門指南

FastAPI是一個現代、快速(高效能)的Python Web框架,用於構建API。本指南將介紹FastAPI的基本概念和使用方法,幫助您快速上手這個強大的工具。

目錄

  1. 安裝
  2. 建立第一個API
  3. 執行伺服器
  4. 路徑引數
  5. 查詢引數
  6. 請求體
  7. 自動API文件
  8. 總結

安裝

首先,您需要安裝FastAPI和一個ASGI伺服器(如Uvicorn)。在命令列中執行以下命令:

pip install fastapi
pip install uvicorn

建立第一個API

讓我們建立一個簡單的FastAPI應用程式。建立一個名為main.py的檔案,並新增以下程式碼:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

這段程式碼建立了一個基本的FastAPI應用,並定義了一個根路由("/"),當訪問時返回一個JSON響應。

執行伺服器

要執行您的FastAPI應用,使用以下命令:

uvicorn main:app --reload

現在,您可以在瀏覽器中訪問 http://127.0.0.1:8000 ,將看到 {"message": "Hello World"} 的JSON響應。

路徑引數

路徑引數是URL路徑中的變數部分。FastAPI允許您輕鬆定義和使用這些引數。

基本用法

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

在這個例子中,item_id 是一個路徑引數。FastAPI會自動解析URL中的值並將其轉換為指定的型別(這裡是 int)。

多個路徑引數

您可以在一個路由中定義多個路徑引數:

@app.get("/users/{user_id}/items/{item_id}")
async def get_user_item(user_id: int, item_id: str):
    return {"user_id": user_id, "item_id": item_id}

這個路由將匹配如 "/users/42/items/foo" 的URL。

路徑引數驗證

FastAPI支援使用Pydantic的欄位驗證:

from fastapi import Path

@app.get("/items/{item_id}")
async def read_item(item_id: int = Path(..., ge=1, le=1000)):
    return {"item_id": item_id}

這個例子確保 item_id 在1到1000之間。

預定義值

您可以使用Enum來限制路徑引數的可能值:

from enum import Enum

class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"

@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}
    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}
    return {"model_name": model_name, "message": "Have some residuals"}

這確保 model_name 只能是 "alexnet"、"resnet" 或 "lenet"。

查詢引數

查詢引數是URL中問號後面的鍵值對。FastAPI讓處理這些引數變得簡單直觀。

基本用法

@app.get("/items/")
async def read_items(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

這個路由可以處理如 "/items/?skip=20&limit=30" 的請求。如果未提供引數,將使用預設值。

可選引數

將引數型別宣告為可選可以使查詢引數成為可選的:

from typing import Optional

@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Optional[str] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

這裡,q 是一個可選的查詢引數。

多個引數

您可以定義任意數量的查詢引數:

@app.get("/users/")
async def read_users(skip: int = 0, limit: int = 10, sort: Optional[str] = None):
    return {"skip": skip, "limit": limit, "sort": sort}

這個路由可以處理如 "/users/?skip=20&limit=30&sort=name" 的請求。

引數驗證

與路徑引數類似,您也可以對查詢引數進行驗證:

from fastapi import Query

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, min_length=3, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

這確保當提供 q 引數時,其長度在3到50個字元之間。

布林型別轉換

FastAPI會自動處理布林型別的查詢引數:

@app.get("/items/")
async def read_items(item_id: str, is_available: bool = False):
    return {"item_id": item_id, "is_available": is_available}

請求 "/items/?item_id=foo&is_available=1" 或 "/items/?item_id=foo&is_available=true" 都會將 is_available 設定為 True

多值查詢引數

有時您可能需要接收同一引數的多個值:

from typing import List

@app.get("/items/")
async def read_items(q: Optional[List[str]] = Query(None)):
    query_items = {"q": q}
    return query_items

這允許處理如 "/items/?q=foo&q=bar" 的請求,其中 q 將是一個包含 "foo" 和 "bar" 的列表。

透過這些詳細的示例和解釋,您應該能夠更好地理解和使用FastAPI中的路徑引數和查詢引數。這些功能允許您建立靈活和強大的API端點,能夠精確地處理各種型別的請求和資料。記住,FastAPI的型別提示不僅提供了型別檢查,還為您的API提供了自動文件生成和請求驗證功能。

請求體

請求體是客戶端傳送到API的資料。在FastAPI中,請求體通常用於POST、PUT和PATCH請求,用來傳送更復雜的資料結構。FastAPI使用Pydantic模型來定義、驗證和序列化請求體。

基本用法

首先,讓我們建立一個基本的請求體模型:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

@app.post("/items/")
async def create_item(item: Item):
    return item

在這個例子中,Item 類定義了請求體的結構。當客戶端傳送POST請求到 "/items/" 時,FastAPI會自動解析JSON請求體並驗證資料。

巢狀模型

您可以建立更復雜的巢狀模型:

class Image(BaseModel):
    url: str
    name: str

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None
    tags: list[str] = []
    image: Image = None

@app.post("/items/")
async def create_item(item: Item):
    return item

這允許您處理包含巢狀結構的JSON資料。

使用請求體和路徑引數

您可以同時使用請求體和路徑引數:

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

這個例子展示瞭如何更新特定ID的專案。

請求體 + 路徑 + 查詢引數

FastAPI允許您結合使用請求體、路徑引數和查詢引數:

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str = None):
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result

多個請求體引數

有時,您可能需要在一個請求中接收多個相關的請求體:

class User(BaseModel):
    username: str
    full_name: str = None

@app.post("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
    results = {"item_id": item_id, "item": item, "user": user}
    return results

在這個例子中,FastAPI會期望一個包含 itemuser 欄位的JSON物件。

請求體中的欄位驗證

Pydantic提供了強大的欄位驗證功能:

from pydantic import BaseModel, Field

class Item(BaseModel):
    name: str
    description: str = Field(None, max_length=300)
    price: float = Field(..., gt=0)
    tax: float = Field(None, ge=0)

@app.post("/items/")
async def create_item(item: Item):
    return item

這個例子使用 Field 來新增額外的驗證:

  • description 的最大長度為300個字元
  • price 必須大於0
  • tax(如果提供)必須大於或等於0

使用 Enum 類

您可以使用 Enum 來限制欄位的可能值:

from enum import Enum

class Color(str, Enum):
    red = "red"
    green = "green"
    blue = "blue"

class Item(BaseModel):
    name: str
    color: Color

@app.post("/items/")
async def create_item(item: Item):
    return item

這確保 color 只能是 "red"、"green" 或 "blue"。

使用 List 和 Set

Pydantic 模型可以包含列表和集合:

from typing import List, Set

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tags: List[str] = []
    unique_tags: Set[str] = set()

@app.post("/items/")
async def create_item(item: Item):
    return item

這允許您處理包含陣列和唯一值集合的JSON資料。

響應模型

您可以使用 Pydantic 模型來定義響應的結構:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class ItemOut(BaseModel):
    name: str
    price: float
    tax: float

@app.post("/items/", response_model=ItemOut)
async def create_item(item: Item):
    return item

在這個例子中,即使函式返回完整的 item,響應將只包含 ItemOut 模型中定義的欄位。

透過這些詳細的示例和解釋,您應該能夠更好地理解和使用FastAPI中的請求體。請求體允許您處理複雜的資料結構,同時利用Pydantic的強大功能進行資料驗證和序列化。這不僅簡化了API的開發過程,還提高了API的穩定性和可靠性。

自動API文件

FastAPI自動為您的API生成互動式文件。啟動您的應用後:

  • 訪問 http://127.0.0.1:8000/docs 檢視Swagger UI文件
  • 訪問 http://127.0.0.1:8000/redoc 檢視ReDoc文件