FastAPI 是一個(gè)用于構(gòu)建 API 的現(xiàn)代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于標(biāo)準(zhǔn)的 Python 類(lèi)型提示。
FastAPI 框架,高性能,易于學(xué)習(xí),高效編碼,生產(chǎn)可用
文檔: https://fastapi.tiangolo.com
源碼: https://github.com/tiangolo/fastapi
FastAPI 是一個(gè)用于構(gòu)建 API 的現(xiàn)代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于標(biāo)準(zhǔn)的 Python 類(lèi)型提示。
關(guān)鍵特性:
快速:可與 NodeJS 和 Go 比肩的極高性能(歸功于 Starlette 和 Pydantic)。最快的 Python web 框架之一。
高效編碼:提高功能開(kāi)發(fā)速度約 200% 至 300%。*
* 根據(jù)對(duì)某個(gè)構(gòu)建線上應(yīng)用的內(nèi)部開(kāi)發(fā)團(tuán)隊(duì)所進(jìn)行的測(cè)試估算得出。
如果你正在開(kāi)發(fā)一個(gè)在終端中運(yùn)行的命令行應(yīng)用而不是 web API,不妨試下 Typer。
Typer 是 FastAPI 的小同胞。它想要成為命令行中的 FastAPI。
Python 3.6 及更高版本
FastAPI 站在以下巨人的肩膀之上:
在命令提示符(macOS或者Linux的終端)中使用pip安裝FastAPI:
pip install fastapi
████████████████████████████████████████ 100%
安裝完FastAPI后還需要一個(gè) ASGI 服務(wù)器來(lái)運(yùn)行相應(yīng)的代碼,生產(chǎn)環(huán)境可以使用 Uvicorn 或者 Hypercorn。
安裝方法也是在命令提示符中使用pip進(jìn)行安裝:
pip install uvicorn
████████████████████████████████████████ 100%
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
或者使用
async def
...如果你的代碼里會(huì)出現(xiàn)
async
/await
,請(qǐng)使用async def
:from typing import Optional from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") async def read_item(item_id: int, q: Optional[str] = None): return {"item_id": item_id, "q": q}
如果你不知道是否會(huì)用到,可以查看文檔的 并發(fā)和異步/等待 章節(jié)中 關(guān)于 async 和 await 的部分。
通過(guò)以下命令運(yùn)行服務(wù)器:
uvicorn main:app --reload
uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
注意:當(dāng)8000端口被占用時(shí),使用該指令會(huì)報(bào)錯(cuò):
[WinError 10013] 以一種訪問(wèn)權(quán)限不允許的方式做了一個(gè)訪問(wèn)套接字的嘗試
。這是由于8000端口被占用導(dǎo)致的,可以通過(guò)更改啟動(dòng)的端口或者kill使用8000端口的應(yīng)用來(lái)解決:
- kill應(yīng)用的方式:在Windows環(huán)境下使用
netstat -aon|findstr "8000"
查看占用8000端口的應(yīng)用的PID,然后在任務(wù)管理器中找到對(duì)應(yīng)應(yīng)用結(jié)束。- 改變啟動(dòng)端口方式(更通用):在啟動(dòng)命令后加
--port
來(lái)改變啟動(dòng)端口,例如uvicorn main:app --reload --port 18080
關(guān)于uvicorn main:app --reload --port 18080
命令
uvicorn main:app
命令含義如下:
main:
main.py文件(一個(gè) Python "模塊")。app
:在 main.py 文件中通過(guò) app = FastAPI() 創(chuàng)建的對(duì)象。--reload
:讓服務(wù)器在更新代碼后重新啟動(dòng)。僅在開(kāi)發(fā)時(shí)使用該選項(xiàng)。--port
:指定啟動(dòng)的端口,該代碼中指定了18080端口。使用瀏覽器訪問(wèn) http://127.0.0.1:8000/items/5?q=somequery。
你將會(huì)看到如下 JSON 響應(yīng):
{"item_id": 5, "q": "somequery"}
你已經(jīng)創(chuàng)建了一個(gè)具有以下功能的 API:
/
和 /items/{item_id}
接受 HTTP 請(qǐng)求。/items/{item_id}
路徑 有一個(gè) 路徑參數(shù) item_id
并且應(yīng)該為 int 類(lèi)型。/items/{item_id}
路徑 有一個(gè)可選的 str 類(lèi)型的 查詢(xún)參數(shù) q。現(xiàn)在訪問(wèn) http://127.0.0.1:8000/docs。
你會(huì)看到自動(dòng)生成的交互式 API 文檔(由 Swagger UI生成):
訪問(wèn) http://127.0.0.1:8000/redoc。
你會(huì)看到另一個(gè)自動(dòng)生成的文檔(由 ReDoc 生成):
現(xiàn)在修改 main.py 文件來(lái)從 PUT 請(qǐng)求中接收請(qǐng)求體。
我們借助 Pydantic 來(lái)使用標(biāo)準(zhǔn)的 Python 類(lèi)型聲明請(qǐng)求體。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
服務(wù)器將會(huì)自動(dòng)重載(因?yàn)樵谏厦娴牟襟E中你向 uvicorn 命令添加了 --reload 選項(xiàng))。
訪問(wèn) http://127.0.0.1:8000/docs。
訪問(wèn) http://127.0.0.1:8000/redoc。
總的來(lái)說(shuō),你就像聲明函數(shù)的參數(shù)類(lèi)型一樣只聲明了一次請(qǐng)求參數(shù)、請(qǐng)求體等的類(lèi)型。
你使用了標(biāo)準(zhǔn)的現(xiàn)代 Python 類(lèi)型來(lái)完成聲明。
你不需要去學(xué)習(xí)新的語(yǔ)法、了解特定庫(kù)的方法或類(lèi),等等。
只需要使用標(biāo)準(zhǔn)的 Python 3.6 及更高版本。
舉個(gè)例子,比如聲明 int 類(lèi)型:
item_id: int
或者一個(gè)更復(fù)雜的 Item 模型:
item: Item
......在進(jìn)行一次聲明之后,你將獲得:
編輯器支持,包括:
數(shù)據(jù)校驗(yàn):
轉(zhuǎn)換 來(lái)自網(wǎng)絡(luò)請(qǐng)求的輸入數(shù)據(jù)為 Python 數(shù)據(jù)類(lèi)型。包括以下數(shù)據(jù):
轉(zhuǎn)換輸出的數(shù)據(jù):轉(zhuǎn)換 Python 數(shù)據(jù)類(lèi)型為供網(wǎng)絡(luò)傳輸?shù)?JSON 數(shù)據(jù):
自動(dòng)生成的交互式 API 文檔,包括兩種可選的用戶(hù)界面:
回到前面的代碼示例,F(xiàn)astAPI 將會(huì):
GET
和 PUT
請(qǐng)求的路徑中是否含有 item_id
。 GET
和 PUT
請(qǐng)求中的 item_id
是否為 int 類(lèi)型。
GET
請(qǐng)求中是否有命名為 q 的可選查詢(xún)參數(shù)(比如 http://127.0.0.1:8000/items/foo?q=somequery)。
雖然我們才剛剛開(kāi)始,但其實(shí)你已經(jīng)了解了這一切是如何工作的。
嘗試更改下面這行代碼:
return {"item_name": item.name, "item_id": item_id}
......從:
... "item_name": item.name ...
......改為:
... "item_price": item.price ...
......注意觀察編輯器是如何自動(dòng)補(bǔ)全屬性并且還知道它們的類(lèi)型:
教程 - 用戶(hù)指南 中有包含更多特性的更完整示例。
劇透警告: 教程 - 用戶(hù)指南中的內(nèi)容有:
獨(dú)立機(jī)構(gòu) TechEmpower 所作的基準(zhǔn)測(cè)試結(jié)果顯示,基于 Uvicorn 運(yùn)行的 FastAPI 程序是 最快的 Python web 框架之一,僅次于 Starlette 和 Uvicorn 本身(FastAPI 內(nèi)部使用了它們)。(*)
想了解更多,請(qǐng)查閱 基準(zhǔn)測(cè)試 章節(jié)。
用于 Pydantic:
用于 Starlette:
用于 FastAPI / Starlette:
你可以通過(guò) pip install fastapi[all] 命令來(lái)安裝以上所有依賴(lài)。
該項(xiàng)目遵循 MIT 許可協(xié)議。
掃描下方二維碼或打開(kāi)微信搜一搜“w3cschool編程獅”關(guān)注公眾號(hào)回復(fù)關(guān)鍵詞【Python123】或者【Python資料包】免費(fèi)領(lǐng)取 Python 學(xué)習(xí)資料,包含軟件安裝包,電子書(shū)、思維導(dǎo)圖等