前言
學習不止
正文
介紹
FastApi是PythonWeb框架的‘新晉干員’,雖然年輕但是很能打
目前已有 12k start
GitHub
官網
為什么說他能打呢?它內部使用了 Python 的 Async 異步,因此速度很快, 也要求必須是 Py3.6+
Async 不同於之前自己實現的 gevent ,Async是官方寫的, 聽說Py4將會大量使用來提高效率
FastApi官網展示了FastApi的特點
快速:非常高的性能,看齊的NodeJS和Go(感謝Starlette和Pydantic)。現有最快的Python框架之一。
快速編碼:將功能開發速度提高約200%至300%。
更少的錯誤:減少約40%的人為錯誤(開發人員)。
直觀:強大的編輯器支持。完成無處不在。調試時間更少。
簡易:旨在易於使用和學習。減少閱讀文檔的時間。
短:最小化代碼重復。每個參數聲明中的多個功能。更少的錯誤。
健壯:獲取可用於生產的代碼。具有自動交互式文檔。
基於標准:基於(並完全兼容)API的開放標准:OpenAPI(以前稱為Swagger)和JSON Schema。
才學了一點點的我已經有了類似的感受
關於效率,官網提供了一個基准測試如下
點我查看
關於官方說的與GO和NodeJS看齊這個可以在學習的最后來與Go的Gin對比一下,日后再說
安裝
我們使用 pip 來安裝
需要注意的是, 官方推薦了可以與 FastApi 搭配的幾個模塊, 基本上涵蓋了幾個大的使用場景
由Pydantic使用:
ujson-用於更快的JSON “解析”。
email_validator -用於電子郵件驗證。
由Starlette使用:
requests-如果要使用,則為必填TestClient。
aiofiles-如果要使用FileResponse或,則為必填StaticFiles。
jinja2 -如果要使用默認模板配置,則為必需。
python-multipart-如果要使用來支持表單“解析”,則為必填request.form()。
itsdangerous-需要SessionMiddleware支持。
pyyaml-Starlette SchemaGenerator支持所必需的(FastAPI 可能不需要它)。
graphene-需要GraphQLApp支持。
ujson-如果要使用,則為必需UJSONResponse。
由FastAPI / Starlette使用:
uvicorn -用於加載和服務您的應用程序的服務器。
orjson-如果要使用,則為必需ORJSONResponse。
您可以使用安裝所有這些pip install fastapi[all]。
也就是說,你可以使用 pip install fastapi[all]
來安裝以上推薦的所有模塊
如果執行時報錯: zsh: no matches found: fastapi[all]
請使用: pip install "fastapi[all]"
如果你不想這樣安裝,請先安裝 兩個必須的模塊,其他按需安裝
pip install fastapi
pip install uvicorn
uvicorn 類似於UWSGI的作用,官網說他與FastApi搭配是性能最佳
HelloWorld
在安裝完依賴后,一切的一切就從 HelloWorld 開始
新建一個 py 文件名叫 main.py
內容如下
from fastapi import FastAPI
app = FastAPI() # 初始化app
@app.get("/") # 監聽GET請求
async def read_root():
return {"hello": "world"} # 返回json
以上就是最簡單的一個 Fast 接口, 需要注意的是, FastApi內部處理網絡io的時候使用的是Async
, 但是進入函數的具體邏輯不受框架控制, 你可以寫成同步,當然寫成異步最佳,這里及本系列后面的都是能用異步則用異步,實在沒有的再用同步
啟動這個項目,在命令行下輸入
uvicorn main:app --reload
這行命令的意思是使用 uvicorn 啟動 main.py 的 app
reload 指檢測到文件改動時自動重載(這在調試時非常有用)
運行后會輸出
(.venv) ➜ fast uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [70401]
INFO: Started server process [70404]
INFO: Waiting for application startup.
INFO: Application startup complete.
代表啟動成功,此時我們可以使用 postman 等調試工具測試接口
以 get 的方式請求 http://127.0.0.1:8000/
返回我們定義的數據為正常
{
"hello": "world"
}
自動生成接口文檔
FastApi 會自己給你生成接口文檔, 真正的解放你的雙手
FastApi 默認提供了兩種接口文檔, 其實內容一樣, 只是使用了兩個開源的文檔框架
swagger
這得益於 swagger 的幫助, swagger的更多使用這里不再贅述
默認的文檔位置在 http://127.0.0.1:8000/docs 使用瀏覽器打開即可
在你更新代碼時接口文檔也會同步更新
redoc
得益於 redoc 的幫助, redoc的更多使用這里不再贅述
默認的文檔位置在 http://127.0.0.1:8000/redoc 使用瀏覽器打開即可
在你更新代碼時接口文檔也會同步更新
get傳參
在 get 請求時,傳遞參數通常使用 url 拼接參數和 query 的方式傳參
url傳參
比如 http://127.0.0.1:8000/phone/123456
在 main.py 中增加函數
@app.get("/phone/{phone}")
async def get_phone(phone: int):
return {"phone": phone}
這里強調一下, phone: int
是聲明參數 phone 是 int 類型,這是 python 3.5+ 有的語法, 目的是增加對開發人員的友好度與IDE的提示, 以后有時間會單獨鋪開講
因我們在啟動時設置了 --reload 所以我們在保存時項目會自己更新, 同時 docs 也會更新
我們訪問url查看結果
{
"phone": 123456
}
query傳參
比如: http://127.0.0.1:8000/user?user_id=12
在函數中是
@app.get("/user")
async def get_user(user_id: int):
return {"user_id": user_id}
復合傳參
如果一個請求中有兩種方式
http://127.0.0.1:8000/user/12?mod=login
對應的是
@app.get("/user/{user_id}")
async def user_mod(user_id: int, mod: str = None): # str = None 代表mod參數可以為空
return {
"user_id": user_id,
"mod": mod
}
返回
{
"user_id": 12,
"mod": "login"
}
body傳參
針對Body傳參的情況, 其實也是以函數傳參的形式, 但是考慮到傳統的 form-data 傳參方式字段很多, 我們可以采用 application/json 的方式, 並且定義一個參數類來管控參數
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel): # 定義一個類用作參數
name: str
price: float
is_offer: bool = None # 該字段可為空
@app.put("/{item_id}")
async def update_item(item_id: int, item: Item): # item需要與Item對象定義保持一致
return {
"item_name": item.name,
"item_id": item_id
}
這里接受 URL 參數與 Body 的 json 格式的參數
舉個例子, 我們使用 postman 調試, Body里設置為 json 傳遞
{
"name": "t1",
"price": 12.8
}
這里注意我們沒有傳遞 is_offer 因為可以為空
url為 http://127.0.0.1:8000/12 , 請求方式為 put, 結果為
{
"item_name": "t1",
"item_id": 12
}
與類型聲明結合
如果你試過在以上幾種接口中傳遞錯誤的參數或者少傳遞參數, 你會發現 FastApi 會自己返回錯誤給客戶端,
比如在參數中定義了 id 為 int 的時候傳遞了 str
沒錯, FastApi 將其與 類型聲明 結合在了一起, 這便是其另一個強大之處,附上官網的解釋
總而言之,您一次將參數,主體等的類型聲明為函數參數。
您可以使用標准的現代Python類型來做到這一點。
您不必學習新的語法,特定庫的方法或類等。
只是標准的Python 3.6+。
例如,對於
int
:item_id: int
或更復雜的
Item
模型:item: Item
...並且使用該單個聲明,您將獲得:
編輯器支持,包括:
- 完成。
- 類型檢查。
數據驗證:
數據無效時自動清除錯誤。
甚至對深度嵌套的JSON對象也進行驗證。
輸入數據的轉換:從網絡轉換為Python數據和類型。讀自:
JSON。
路徑參數。
查詢參數。
餅干。
標頭。
形式。
文件。
轉換
輸出的數據:從Python數據和類型轉換為網絡數據(JSON):
- 轉換的Python類型(
str
,int
,float
,bool
,list
,等)。datetime
對象。UUID
對象。- 數據庫模型。
- ...還有很多。
自動交互式API文檔,包括2個備用用戶界面:
- 招搖UI。
- ReDoc。
回到前面的代碼示例,FastAPI將:
驗證和請求
item_id
的路徑中是否存在。PUT
驗證
item_id
的類型int
為PUT
請求。如果不是,客戶端將看到一個有用的明確錯誤。
對於
PUT
請求/items/{item_id}
,請以JSON格式讀取正文:檢查其是否具有必填屬性
name
,該屬性應為str
。檢查其是否具有必填屬性
price
,該屬性必須為float
。檢查它是否具有可選屬性,如果存在
is_offer
,則應為bool
。所有這些對於深度嵌套的JSON對象也適用。
自動從和轉換為JSON。
使用OpenAPI記錄所有內容,可用於:
- 交互式文檔系統。
- 自動客戶端代碼生成系統,適用於多種語言。
直接提供2個交互式文檔Web界面。