快速使用FastAPI !
新版本的Python在類型提示上的功能越來越完善,使用FastAPI 可以讓API進行變數匹配、驗證簡單,同時Asyncio 得到越來越多的支持。
之前在python的限制下,CPU綁定可以通過multiprocessing或者其他套件來支持,但是IO綁定增加io進程的代價實在是太高了,所以通過asyncio來彌補這些問題則是目前發展方向,從此套件衍生出的 FastAPI 就可以說是時代趨勢。
FastAPI 寫法類似於Flask。此外,FastAPI 可以自動生成api文件!
Env 安裝環境
就一行。
pip install "fastapi[all]"
File
這邊我們要創建一些檔案。 這些檔案會引導我們完成一個基本的API。
- ./main.py
import uvicorn
from fastapi import FastAPI
from type.response import JsonResponMsg, Msg
from type.client import UserID, User
app = FastAPI()
@app.get("/userID", response_model=JsonResponMsg)
async def getUserById(userID: UserID) -> JsonResponMsg:
return {
"status": 200,
"body": {
"message": f"args- {userID}",
"tag": f"args- {userID}"
}
}
@app.post("/userID", response_model=JsonResponMsg)
async def newUserById(user: User) -> JsonResponMsg:
return JsonResponMsg(
status= 200,
body=Msg(
message=user["name"],
tag=str(user["userId"])
)
)
uvicorn.run(app, host="0.0.0.0", port=8080)
這邊我們定義一些類型,這有助於我們程式更加穩固。
- ./type/client.py
from typing import NewType, TypedDict
UserID = NewType("UserID", int)
class User(TypedDict):
userId: UserID
name: str
- ./type/response.py
from typing import TypedDict
class Msg(TypedDict):
message: str
tag: str
class JsonResponBase(TypedDict):
status: int
class JsonResponMsg(JsonResponBase):
body: Msg
Up server
python -m main.py
Swagger UI
http://127.0.0.1:8000/docs
Static File ** optional **
預設的情況下,fastapi會去網路上下載一些輔助的js檔案來完成swagger-ui。
但我們也可以事先下載下來,做為一個靜態資源來取用。
## Guildline: https://fastapi.tiangolo.com/advanced/extending-openapi/#download-the-files
- ./static/swagger-ui-bundle.js
- ./static/swagger-ui.css
## Download & Save plugin in here.
swagger-ui-bundle.js: https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js
swagger-ui.css: https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css
- 更新 ./main.py
請基於之前的 ./main.py 進行更新。
from fastapi.staticfiles import StaticFiles
from type.response import JsonResponMsg, Msg
...
...
...
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
...
...
...
@app.get("/docs", include_in_schema=False)
async def swagger_ui():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title="api docs",
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css"
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()