TL;DR
FastAPI
是近期受到矚目的網頁框架,與Python常用的框架 Flask
、 Django
相同,可以用來建立 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
基本結構
與 Flask
的 run.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
相當類似。
FastAPI
與 Flask
不同的地方在於:
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