手冊(cè)簡(jiǎn)介

FastAPI 是一個(gè)用于構(gòu)建 API 的現(xiàn)代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于標(biāo)準(zhǔn)的 Python 類(lèi)型提示。

手冊(cè)說(shuō)明


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%。*

  • 更少 bug:減少約 40% 的人為(開(kāi)發(fā)者)導(dǎo)致錯(cuò)誤。*
  • 智能:極佳的編輯器支持。處處皆可自動(dòng)補(bǔ)全,減少調(diào)試時(shí)間。
  • 簡(jiǎn)單:設(shè)計(jì)的易于使用和學(xué)習(xí),閱讀文檔的時(shí)間更短。
  • 簡(jiǎn)短:使代碼重復(fù)最小化。通過(guò)不同的參數(shù)聲明實(shí)現(xiàn)豐富功能。bug 更少。
  • 健壯:生產(chǎn)可用級(jí)別的代碼。還有自動(dòng)生成的交互式文檔。
  • 標(biāo)準(zhǔn)化:基于(并完全兼容)API 的相關(guān)開(kāi)放標(biāo)準(zhǔn):OpenAPI (以前被稱(chēng)為 Swagger) 和 JSON Schema。

* 根據(jù)對(duì)某個(gè)構(gòu)建線上應(yīng)用的內(nèi)部開(kāi)發(fā)團(tuán)隊(duì)所進(jìn)行的測(cè)試估算得出。


Typer,命令行中的 FastAPI


如果你正在開(kāi)發(fā)一個(gè)在終端中運(yùn)行的命令行應(yīng)用而不是 web API,不妨試下 Typer。

Typer 是 FastAPI 的小同胞。它想要成為命令行中的 FastAPI。 

依賴(lài)

Python 3.6 及更高版本

FastAPI 站在以下巨人的肩膀之上:

  • Starlette 負(fù)責(zé) web 部分。
  • Pydantic 負(fù)責(zé)數(shù)據(jù)部分。

安裝

在命令提示符(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%

示例

創(chuàng)建

  • 創(chuàng)建一個(gè) main.py 文件并寫(xiě)入以下內(nèi)容:
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 的部分。

運(yùn)行

通過(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)解決:

  1. kill應(yīng)用的方式:在Windows環(huán)境下使用netstat -aon|findstr "8000"查看占用8000端口的應(yīng)用的PID,然后在任務(wù)管理器中找到對(duì)應(yīng)應(yīng)用結(jié)束。
  2. 改變啟動(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:

  • 通過(guò) 路徑 /  /items/{item_id} 接受 HTTP 請(qǐng)求。
  • 以上 路徑 都接受 GET 操作(也被稱(chēng)為 HTTP 方法)。
  • /items/{item_id} 路徑 有一個(gè) 路徑參數(shù) item_id 并且應(yīng)該為 int 類(lèi)型。
  • /items/{item_id} 路徑 有一個(gè)可選的 str 類(lèi)型的 查詢(xún)參數(shù) q。

交互式 API 文檔

現(xiàn)在訪問(wèn) http://127.0.0.1:8000/docs。

你會(huì)看到自動(dòng)生成的交互式 API 文檔(由 Swagger UI生成):


可選的 API 文檔

訪問(wèn) http://127.0.0.1:8000/redoc。

你會(huì)看到另一個(gè)自動(dòng)生成的文檔(由 ReDoc 生成):


示例升級(jí)

現(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))。

交互式 API 文檔升級(jí)

訪問(wèn) http://127.0.0.1:8000/docs

  • 交互式 API 文檔將會(huì)自動(dòng)更新,并加入新的請(qǐng)求體:


  • 點(diǎn)擊「Try it out」按鈕,之后你可以填寫(xiě)參數(shù)并直接調(diào)用 API:


  • 然后點(diǎn)擊「Execute」按鈕,用戶(hù)界面將會(huì)和 API 進(jìn)行通信,發(fā)送參數(shù),獲取結(jié)果并在屏幕上展示:


可選文檔升級(jí)

訪問(wèn) http://127.0.0.1:8000/redoc

  • 可選文檔同樣會(huì)體現(xiàn)新加入的請(qǐng)求參數(shù)和請(qǐng)求體:


總結(jié)

總的來(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)行一次聲明之后,你將獲得:

編輯器支持,包括:

  • 自動(dòng)補(bǔ)全 
  • 類(lèi)型檢查

數(shù)據(jù)校驗(yàn):

  • 在校驗(yàn)失敗時(shí)自動(dòng)生成清晰的錯(cuò)誤信息。
  • 對(duì)多層嵌套的 JSON 對(duì)象依然執(zhí)行校驗(yàn)

轉(zhuǎn)換 來(lái)自網(wǎng)絡(luò)請(qǐng)求的輸入數(shù)據(jù)為 Python 數(shù)據(jù)類(lèi)型。包括以下數(shù)據(jù):

  • JSON
  • 路徑參數(shù)
  • 查詢(xún)參數(shù)
  • Cookies
  • 請(qǐng)求頭
  • 表單文件

轉(zhuǎn)換輸出的數(shù)據(jù):轉(zhuǎn)換 Python 數(shù)據(jù)類(lèi)型為供網(wǎng)絡(luò)傳輸?shù)?JSON 數(shù)據(jù):

  • 轉(zhuǎn)換 Python 基礎(chǔ)類(lèi)型 (str、 int、 float、 bool、 list 等)
  • datetime 對(duì)象
  • UUID 對(duì)象
  • 數(shù)據(jù)庫(kù)模型
  • .....以及更多其他類(lèi)型

自動(dòng)生成的交互式 API 文檔,包括兩種可選的用戶(hù)界面:

  • Swagger UI
  • ReDoc

    回到前面的代碼示例,F(xiàn)astAPI 將會(huì):

    • 校驗(yàn) GET  PUT 請(qǐng)求的路徑中是否含有 item_id。
    • 校驗(yàn) GET  PUT 請(qǐng)求中的 item_id 是否為 int 類(lèi)型。
      • 如果不是,客戶(hù)端將會(huì)收到清晰有用的錯(cuò)誤信息。
    • 檢查 GET 請(qǐng)求中是否有命名為 q 的可選查詢(xún)參數(shù)(比如 http://127.0.0.1:8000/items/foo?q=somequery)。
      • 因?yàn)?nbsp;q 被聲明為 = None,所以它是可選的。
      • 如果沒(méi)有 None 它將會(huì)是必需的 (如 PUT 例子中的請(qǐng)求體)。
    • 對(duì)于訪問(wèn) /items/{item_id} 的 PUT 請(qǐng)求,將請(qǐng)求體讀取為 JSON ,同時(shí):
      • 檢查是否有必需屬性 name 并且值為 str 類(lèi)型 。
      • 檢查是否有必需屬性 price 并且值為 float 類(lèi)型。
      • 檢查是否有可選屬性 is_offer, 如果有的話(huà)值應(yīng)該為 bool 類(lèi)型。
      • 以上過(guò)程對(duì)于多層嵌套的 JSON 對(duì)象同樣也會(huì)執(zhí)行
    • 自動(dòng)對(duì) JSON 進(jìn)行轉(zhuǎn)換或轉(zhuǎn)換成 JSON。
    • 通過(guò) OpenAPI 文檔來(lái)記錄所有內(nèi)容,可被用于:
      • 交互式文檔系統(tǒng)
      • 許多編程語(yǔ)言的客戶(hù)端代碼自動(dòng)生成系統(tǒng)
    • 直接提供 2 種交互式文檔 web 界面。

    雖然我們才剛剛開(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)容有:

    • 對(duì)來(lái)自不同地方的參數(shù)進(jìn)行聲明,如:請(qǐng)求頭、cookies、form 表單以及上傳的文件。
    • 如何設(shè)置校驗(yàn)約束如 maximum_length 或者 regex。
    • 一個(gè)強(qiáng)大并易于使用的 依賴(lài)注入 系統(tǒng)。
    • 安全性和身份驗(yàn)證,包括通過(guò) JWT 令牌和 HTTP 基本身份認(rèn)證來(lái)支持 OAuth2。
    • 更進(jìn)階(但同樣簡(jiǎn)單)的技巧來(lái)聲明 多層嵌套 JSON 模型 (借助 Pydantic)。
    • 許多額外功能(歸功于 Starlette)比如:
      • WebSockets
      • GraphQL
      • 基于 requests 和 pytest 的極其簡(jiǎn)單的測(cè)試
      • CORS
      • Cookie Sessions
      • ......以及更多

    性能

    獨(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é)。

    可選依賴(lài)

    用于 Pydantic:

    • ujson - 更快的 JSON 「解析」。
    • email_validator - 用于 email 校驗(yàn)。

    用于 Starlette:

    • requests - 使用 TestClient 時(shí)安裝。
    • aiofiles - 使用 FileResponse 或 StaticFiles 時(shí)安裝。
    • jinja2 - 使用默認(rèn)模板配置時(shí)安裝。
    • python-multipart - 需要通過(guò) request.form() 對(duì)表單進(jìn)行「解析」時(shí)安裝。
    • itsdangerous - 需要 SessionMiddleware 支持時(shí)安裝。
    • pyyaml - 使用 Starlette 提供的 SchemaGenerator 時(shí)安裝(有 FastAPI 你可能并不需要它)。
    • graphene - 需要 GraphQLApp 支持時(shí)安裝。
    • ujson - 使用 UJSONResponse 時(shí)安裝。

    用于 FastAPI / Starlette:

    • uvicorn - 用于加載和運(yùn)行你的應(yīng)用程序的服務(wù)器。
    • orjson - 使用 ORJSONResponse 時(shí)安裝。

    你可以通過(guò) pip install fastapi[all] 命令來(lái)安裝以上所有依賴(lài)。

    許可協(xié)議

    該項(xiàng)目遵循 MIT 許可協(xié)議。


    領(lǐng)取免費(fèi)資料

    掃描下方二維碼或打開(kāi)微信搜一搜“w3cschool編程獅”關(guān)注公眾號(hào)回復(fù)關(guān)鍵詞【Python123】或者【Python資料包】免費(fèi)領(lǐng)取 Python 學(xué)習(xí)資料,包含軟件安裝包,電子書(shū)、思維導(dǎo)圖等

    w3cschool編程獅微信公眾號(hào)

    在線筆記
    App下載
    App下載

    掃描二維碼

    下載編程獅App

    公眾號(hào)
    微信公眾號(hào)

    編程獅公眾號(hào)