Fast API 入門筆記 (一) - 基本介紹

Posted by MingLun Allen Wu on Thursday, January 21, 2021

TL;DR

FastAPI 是近期受到矚目的網頁框架,與Python常用的框架 FlaskDjango 相同,可以用來建立 API 及網頁服務, 用以下幾點來概括 FastAPI 的特色:

  • 快速: 如同它的名字,執行速度相當快速,是當前最快的Python框架
  • 直覺FastAPI 使用 OpenAPI 的開源標準,所以在開發時,能夠套用 auto complete
  • 自動產生文件: API撰寫完成後,FastAPI 會自動產生對應的文件。
  • 簡單: 語法上與 Flask 相差不大,轉換陣痛並不高。

Requirements & Installation

  • Python 環境 : Python 3.6 +

  • 基本套件:

   pip install fastapi # FastAPI
   pip install uvicorn[standard] # ASGI Server

撰寫第一支API

基本結構

Flaskrun.py 類似, 可以將所有程式碼放在 main.py 中,快速建立第一個 FastAPI

在語法結構上,與 Flask 大同小異,,也是透過 @app 裝飾子來定義API路徑。

不過 FastAPI 在定義路徑時,會透過裝飾子一併定義 API 可提供的 HTTP Method:

  • @app.post() : Post 方法
  • @app.get() : Get 方法
  • @app.put() : Put 方法
  • @app.delete() : Delete 方法

了解裝飾子的概念後,參考官方文件的範例,在main.py 中輸入:

from typing import Optional

from fastapi import FastAPI

app = FastAPI() # 建立一個 Fast API application

@app.get("/") # 指定 api 路徑 (get方法)
def read_root():
    return {"Hello": "World"}


@app.get("/users/{user_id}") # 指定 api 路徑 (get方法)
def read_user(user_id: int, q: Optional[str] = None):
    return {"user_id": user_id, "q": q}

啟動服務

Flask 不同的是,如果直接執行此 main.py 不會啟動服務

需要透過 ASGI Server gvicorn 來啟用:

uvicorn main:app --reload
# uvicorn <檔名>:<app名稱>
# --reload 在專案更新時,自動重新載入,類似Flask的debug模式

啟用後在瀏覽器輸入 127.0.0.1:8000/users/8?q=minglunwu,將會得到如下的回傳結果:

{"user_id":8,"q":"minglunwu"}

當我們鍵入 127.0.0.1:8000/users/8?q=minglunwu時, FastAPI 會在定義好的裝飾子中,尋找符合路徑前綴: /users 的 function,也就是 read_user()。 這部分的機制與 Flask 相當類似。

FastAPIFlask 不同的地方在於:

FastAPI 在建立API時,需要以 型態提示 (Typing Hints) 來定義參數的型態

型態提示(Typing Hints)

舉例來說: 在上圖的 read_user() 中,我們定義了以下的格式:

@app.get("/users/{user_id}") # 指定 api 路徑 (get方法)
def read_user(user_id: int, q: Optional[str] = None):
    return {"user_id": user_id, "q": q}

在定義 Function 的參數時,使用 Python 內建的型態檢查語法,指定各參數的型態,以上圖的Function來看,我們分別設定了下列的參數及型態:

  • user_id: int格式
  • q: str格式(Optional)

使用 Typing Hint 有兩項優點:

1. FastAPI 在收到請求時,會自動檢查參數的格式是否符合條件

FastAPI 收到 Request時,會先檢查URL,尋找符合 @app 所定義的路徑規則。

在解析 Request 所攜帶的參數時,將比對定義的變數型態,如果有不符合的,將會回傳錯誤訊息,舉例來說:

如果我們嘗試在瀏覽器中輸入 不符合規則的URL:

127.0.0.1:8000/users/error_type?q=minglunwu

(將原本的整數 8 換成字串 error_type)

此時因為收到的參數 error_type?q=minglunwu 因為參數 error_type 並不符合預先定義好的參數型態: int,此次Request無效。

不像 Flask 會回傳驚心動魄的錯誤訊息, FastAPI 會自動將錯誤訊息轉換成下列「有用」且「清楚」的錯誤訊息後,進行回傳:

{"detail":[
    {"loc":["path","user_id"],"msg":"value is not a valid integer","type":"type_error.integer"}
    ]
}

2. 自動轉換文件

FastAPI 的另一項特色在於:

自動生成 API 文件

完成了第一支 API 後,在瀏覽器輸入: http://127.0.0.1:8000/docs:

可以看到在畫面中,除了API的名稱外,參數的型態及Response的結果都包含在自動產生的文件中!

除了方便使用者閱讀外,這些文件也有提供即時互動功能,能夠即時測試:

撰寫API是一件費力耗神的工作,我曾傻傻地使用 Markdown 手刻文件,大概寫到十來個函式時就崩潰放棄 Orz

後來嘗試使用 Sphinx 工具,能直接將註解轉換為文件,不過在使用時還需要再多進行一次轉換,稍嫌麻煩。

個人蠻喜歡FastAPI 內建的轉換功能,在撰寫好API的同時就自動產生完整的文件。


前往下集:

Fast API 入門筆記 (二) - Typing Hint & Async



See Also

監控資料品質的旅程