Skip to content

[Python] 使用 FastAPI 框架進行後端開發筆記

Last Updated on 2023-07-02 by Clay

Introduction

FastAPI 是一個現代、高效的 Python web 框架。基於 python 3.7+ 並且擁有 python type hints。

可能大家會奇怪,如果要使用 Python 寫一個網站,使用 Flask 或 Django 不是最普遍的嗎?為什麼要採用 FastAPI 呢?

以下簡單記錄一下 FastAPI 和 Flask 這兩個框架之間的差異。

  1. 現代性和標準
    FastAPI 是比較新的框架,並且是專門為 RESTful APIs 而設計的。它採用了現代的 Python 特性(如 type hint),並符合最新的標準,如 OpenAPI 和 JSON Schema。
    相較之下,Flask 是一個更傳統的、普遍用於通用網路開發的輕量化框架。
  2. 性能
    FastAPI 的性能通常要優於 Flask。
    FastAPI 是異步編程的,這使它能夠更有效地處理大量請求,並且通常具有更低的延遲。
    而 Flask 是同步的,並且通常在高負載下的性能不及 FastAPI。
  3. 類型檢查和數據驗證
    剛剛上面也有提到,FastAPI 能夠使用 Python 的類型提示來進行自動資料驗證和序列化。這不僅可以消除大量的模板代碼,而且還提供了自動生成的 API 文檔。
    而在 Flask 中,我們通常需要手動進行數據驗證和序列化。
  4. 自動文件生成
    FastAPI 自動生成交互式 API 文檔(通過 Swagger UI 或 ReDoc),這使得開發和測試過程更加容易。而 Flask 需要使用第三方擴展來生成 API 文件。
  5. 學習難易度
    對於新手來說,Flask 的學習曲線可能略微平緩一些,因為它的設計較為簡單和傳統。FastAPI 則需要開發人員熟悉更多的現代特性,如異步編程和類型提示。
  6. 社群和生態系
    Flask 由於已經存在很長時間,因此擁有一個龐大的社群和大量的插件和擴展。FastAPI 雖然社群正在快速增長,但相對於 Flask 來說還是較小的。

總結還說,選擇 FastAPI 還是 Flask 取決於我們對於設計的應用程式具體需求。

比方說,如果你的目的主要是創建 RESTful API,那麼 FastAPI 可能是比較好的選擇,因為它正是為此而設計的。

但如果你需要一個通用的網路框架,用於處理各種不同類型的應用程序,那麼 Flask 可能是更適合的。

以下,簡單紀錄 FastAPI 的需求、安裝與使用方法吧!


Requirements

Python 3.7+


Installation

pip install fastapi unicorn[standard]


你將會需要 ASGI server (Asynchronous Server Gateway Interface),所以也請安裝 uvicorn。官方還提到了另外一項工具 hypercorn,如果有需要,或許也可以考慮安裝此項。


Example

# main.pyfrom typing importUnionfrom fastapi import FastAPI

app = FastAPI()


@app.get("/")defread_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")defread_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}


如果要用異步處理(Asynchronous Processing)的話,則需要寫成以下的形式:

# main.pyfrom typing importUnionfrom fastapi import FastAPI

app = FastAPI()


@app.get("/")asyncdefread_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")asyncdefread_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}


接著你可以直接執行:

uvicorn main:app --reload

其中,--reload 參數可以讓我們在每次變更程式碼時,界面會自動重新載入,不用手動重啟。

然後從 http://127.0.0.1:8000 可以體驗結果,或是從 http://127.0.0.1:8000/items/5?q=somequery 測試另外一個路由。

目前,我們已經成功建立一個測試用的網頁。


Some Help

我們可以從下面的 URL 得到一些目前測試的功能與路由的幫助。
http://127.0.0.1:8000/docs


put and post Example

post 是針對功能發送請求的動作、put 則是對既有資料進行更新的動作。

# coding: utf-8from typing importUnion, Dictfrom fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


# Database
hero_db = {}


# Hero data modelclassHero(BaseModel):
    name: str
    age: int
    ability: str
    hero_id: int# POST example: add a new [email protected]("/heroes/")asyncdefcreate_hero(hero: Hero):
    hero_db[hero.hero_id] = hero.dict()
    return {"Message": "Hero add", "data": hero}


@app.put("/heroes/{hero_id}")asyncdefupdate_hero(hero_id: int, hero: Hero):
    if hero_id in hero_db:
        hero_db[hero_id] = hero.dict()
        return {"message": "Hero updated", "data": hero}
    else:
        return {"message": "Hero not found"}


使用 post 來新增一名英雄。

curl -X POST "http://127.0.0.1:8000/heroes/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"Batman\",\"age\":35,\"ability\":\"Martial Arts\",\"hero_id\":1}"


使用 put 來更新該名英雄的資訊。

curl -X PUT "http://127.0.0.1:8000/heroes/1" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"Bruce Wayne\",\"age\":36,\"ability\":\"Detective\",\"hero_id\":1}"


至此,我們已經完成了 FastAPI 幾項最基本的操作了。


References


Read More

Tags:

Leave a Reply