FastApi學習(一)


前言

學習不止

正文

介紹

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類型(strintfloatboollist,等)。
    • datetime 對象。
    • UUID 對象。
    • 數據庫模型。
    • ...還有很多。
  • 自動交互式API文檔,包括2個備用用戶界面:

    • 招搖UI。
    • ReDoc。

回到前面的代碼示例,FastAPI將:

  • 驗證和請求item_id的路徑中是否存在。PUT

  • 驗證 item_id 的類型 intPUT 請求。

  • 如果不是,客戶端將看到一個有用的明確錯誤。

  • 對於 PUT 請求 /items/{item_id} ,請以JSON格式讀取正文:

  • 檢查其是否具有必填屬性name,該屬性應為str

  • 檢查其是否具有必填屬性price,該屬性必須為float

  • 檢查它是否具有可選屬性,如果存在is_offer,則應為bool

  • 所有這些對於深度嵌套的JSON對象也適用。

  • 自動從和轉換為JSON。

  • 使用OpenAPI記錄所有內容,可用於:

    • 交互式文檔系統。
    • 自動客戶端代碼生成系統,適用於多種語言。
  • 直接提供2個交互式文檔Web界面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM