全面擁抱 FastApi —— 三大參數及驗證


點擊「 Python編程與實戰 」,選擇「置頂公衆號」

第一時間獲取 Python 技術乾貨!web

前幾天寫了一篇關於 FastApi 進階的多應用程序管理藍圖APIRouter,編程

全面擁抱 FastApi — 多應用程序項目結構規劃
api

可能對於有些沒有基礎的朋友看起來會有點懵,因此後面會按照由淺及深的順序進行更新,記得關注噢!
瀏覽器

先看下 FastAPI 有哪些突出特色,官網介紹以下:服務器

快速:很是高的性能,性能可與NodeJSGo相媲美(感謝Starlette 和 Pydantic)。現有最快的Python框架之一。微信

快速編碼:將功能開發速度提升約200%至300%*。app

更少的錯誤:減小約40%的人爲錯誤(開發人員)。框架

直觀:強大的編輯器支持,程序調試時間更少。異步

簡易:易於使用和學習,減小閱讀文檔的時間。async

:最小化重複代碼,每一個參數聲明中的多個功能,減小編碼錯誤。

健壯:獲取可用於生產的代碼。具備自動交互式的 API 文檔。

基於標準:基於(並徹底兼容)API 的開放標準:OpenAPI(之前稱爲Swagger)和JSON Schema。

前面說過 FastApi 的一大特色是基於標準的 Python 3.6類型聲明,兼具參數校驗功能,這一切都要歸功於 Pydantic

路徑參數

路徑參數即 url 路徑參數,能夠使用 Python 格式字符串相同語法聲明路徑「參數」或「變量」,例如:

from fastapi import FastAPI
app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item": item_id, "q": q}

path 參數的值 item_id 將做爲參數傳遞給視圖函數,運行命令:

uvicorn 文件名:app

默認端口是 8000,也能夠指定 host 和 port , --host=0.0.0.0 --port=8008

運行以後,在瀏覽器中打開 http://127.0.0.1:8000/items/1,能夠看到響應:

{"item":1,"q":null}

其中 item_id 被聲明爲 int 類型,q 爲 可選參數,默認爲None,因此響應中的 q 是 None

當咱們經過 http://127.0.0.1:8000/items/test 去訪問的時候, 能夠看到一個很是友好的錯誤響應

{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}

由於 path 參數 item_id 的值是 "test" 不能轉爲 int,這就是參加驗證

查詢參數

查詢參數也是帶在 url 地址中的,是 url 中位於 ?以後的一組鍵值對,以 & 字符分隔,這對爬蟲朋友來講再熟悉不過了,好比下面的請求參數

data = {"test": 1, "name": "Python編程與實戰"}
response = requests.get(url, params=data)

以 關鍵字參數 params 傳過去的就是查詢參數,你能夠將其中的 response.url 打印出來便可看到 ?以後的鍵值對參數

那麼在服務端 FastApi 如何來接收這種參數呢? 請看代碼

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]

運行後輸入地址:http://127.0.0.1:8000/items/?skip=0&limit=10

查詢參數爲:

  • skip:值爲 0
  • limit:值爲 10 注意這兩個參數都帶有默認值,能夠選擇只傳一個

可選參數

一樣,您能夠經過將可選查詢參數的默認值設置爲來聲明可選查詢參數 None

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}

必需查詢參數

將上面代碼中的 q: str 去掉 None,則 q 變成了必須查詢參數,也就是必傳的,不然會提示錯誤

{
"detail": [
{
"loc": [
"query",
"q"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}

給大夥總結一下,在實際代碼中可能會用到必需參數,默認參數,可選參數,以下:

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str, skip: int = 0, limit: int = None):
item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
return item

在這種狀況下,有3個查詢參數:

  • needy,是必需的 str 。
  • skip,int 默認值爲 0。
  • limit,可選的 int。

其中還有一個是路徑參數:item_id, str 類型

請求體參數

要發送請求正文,必須使用一個:POST, PUT,DELETE或PATCH,需導入 Pydantic 的 BaseModel

from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel

app = FastAPI()

class CommonItem(BaseModel):
token: str
message_id: str
to_id: str
from_info: str
strategy: int or str = 0 # 默認爲0,可不傳該參數,可是不能傳空字符串
type: str or int # str 和 int 類型都支持
from_id: str
to_info: str
content: str = None

@app.post("/test")
async def tests(item: CommonItem):
return item

能夠看到,建立了一個 CommonItem 模型,有了聲明的這個模型,能夠實現如下功能:

  • 以 JSON 讀取請求的正文
  • 根據聲明的類型,自動對參數進行轉換
  • 驗證數據,若是數據無效,它將返回一個清晰的錯誤,指出錯誤數據的確切位置和來源
  • 在參數中接收收到的數據 item,並能獲取全部屬性及全部編輯器的支持

同時,FastApi 能夠自動幫咱們識別請求 body 參數, 路徑參數以及查詢參數,並準確的獲取參數數據。例如如下代碼:

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None

app = FastAPI()

@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: str = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result

上述代碼,參數將被自動識別:

  • item_id: 路徑參數
  • q: 參數是一個的單一類型(如int,float,str,bool,等等)將被解釋爲一個查詢參數
  • item: 參數聲明爲 Pydantic 模型的類型,則將被解釋爲請求 body


推薦閱讀


Python 異步 ASGI 服務器及框架

Flask 表單驗證之 WTForms




THANKS

- End -


點個「在看」必升職加薪喔!

本文分享自微信公衆號 - Python編程與實戰(GoPy1024)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索