1. 什么是FastAPI?
FastAPI 是一個(gè)用于構(gòu)建 API 的現(xiàn)代爷抓、快速(高性能)的 web 框架尸曼,使用 Python 3.6+ 并基于標(biāo)準(zhǔn)的 Python 類型提示,
fastapi 是python最快的web框架叮雳。
"""
特性:
1.快速,比肩go
2.編碼快速,開(kāi)發(fā)快
3.減少人為bug
4.智能,自動(dòng)補(bǔ)全, 減少調(diào)試時(shí)間
5.設(shè)計(jì)易于學(xué)習(xí),文檔簡(jiǎn)單
6.簡(jiǎn)短: 代碼量小,bug更少
7.健壯:生產(chǎn)場(chǎng)景,生成交互式文檔
8.標(biāo)準(zhǔn)化:基于API的相關(guān)的開(kāi)放標(biāo)準(zhǔn)
"""
2.安裝
pip install fastapi
# 依賴
pip install uvicorn[standard]
3.最小愛(ài)快速示例:
import uvicorn
from typing import Optional, Set
from fastapi import FastAPI, Path, Query
from pydantic import BaseModel
app = FastAPI() # 這里的變量 app 會(huì)是 FastAPI 類的一個(gè)「實(shí)例」,
# 這個(gè)實(shí)例將是創(chuàng)建你所有API 的主要交互對(duì)象,每個(gè)接口@app.get/put中的app。
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}
3.運(yùn)行
# 3.1 命令運(yùn)行:
uvicorn main:app --reload
# 3.2 代碼運(yùn)行:
if __name__ == '__main__':
uvicorn.run(app=app, host="10.148.228.113", port=65500, workers=1)
4.性能優(yōu)異
基于 Uvicorn 運(yùn)行的 FastAPI 程序是 最快的 Python web框架之一,支持異步和并發(fā)
5.類型提示:
同樣以冒號(hào)(:)來(lái)聲明這個(gè)變量。
6.Pydantic 模型?
Pydantic 是一個(gè)用來(lái)用來(lái)執(zhí)行數(shù)據(jù)校驗(yàn)的 Python 庫(kù)。
7.路徑操作裝飾器
# 在開(kāi)發(fā) API 時(shí)密浑,你通常使用特定的 HTTP 方法去執(zhí)行特定的行為
# POST:創(chuàng)建數(shù)據(jù)粗井。
# GET:讀取數(shù)據(jù)尔破。
# PUT:更新數(shù)據(jù)。
# DELETE:刪除數(shù)據(jù)浇衬。
8.fastapi程序的步驟:
導(dǎo)入 FastAPI懒构。
創(chuàng)建一個(gè) app 實(shí)例。
編寫一個(gè)路徑操作裝飾器(如 @app.get("/"))耘擂。
編寫一個(gè)路徑操作函數(shù)(如上面的 def root(): ...)胆剧。
運(yùn)行開(kāi)發(fā)服務(wù)器(如 uvicorn main:app --reload)。
9.路徑參數(shù)
路徑參數(shù) item_id 的值將作為參數(shù) item_id 傳遞給你的函數(shù)
由于路徑操作是按順序依次運(yùn)行的醉冤,
你需要確保路徑 /users/me 聲明在路徑 /users/{user_id}之前:
否則秩霍,/users/{user_id} 的路徑還將與 /users/me 相匹配,
"認(rèn)為"自己正在接收一個(gè)值為 "me" 的 user_id 參數(shù)蚁阳。
10.查詢參數(shù)
聲明不屬于路徑參數(shù)的其他函數(shù)參數(shù)時(shí)铃绒,它們將被自動(dòng)解釋為"查詢字符串"參數(shù)
查詢字符串是鍵值對(duì)的集合,這些鍵值對(duì)位于 URL 的 螺捐? 之后颠悬,并以 & 符號(hào)分隔。
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]
11.請(qǐng)求體參數(shù)
請(qǐng)求體是客戶端發(fā)送給 API 的數(shù)據(jù)归粉。響應(yīng)體是 API 發(fā)送給客戶端的數(shù)據(jù)椿疗。 注意: 要發(fā)送數(shù)據(jù),你必須使用下列方法之一:POST(較常見(jiàn))糠悼、PUT届榄、DELETE 或 PATCH。
"""
使用 Pydantic 模型來(lái)聲明請(qǐng)求體
from pydantic import BaseModel
當(dāng)一個(gè)模型屬性具有默認(rèn)值時(shí)倔喂,它不是必需的
"""
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
12.查詢參數(shù)和字符串校驗(yàn)
當(dāng)你在使用 Query 且需要聲明一個(gè)值是必需的時(shí)铝条,可以將 ... 用作第一個(gè)參數(shù)值:
"""
通用的校驗(yàn)和元數(shù)據(jù):
alias
title
description
deprecated
特定于字符串的校驗(yàn):
min_length
max_length
regex
"""
13.路徑參數(shù)和數(shù)值校驗(yàn)
# 可以使用 Path 為路徑參數(shù)聲明相同類型的校驗(yàn)和元數(shù)據(jù)。
# 路徑參數(shù)總是必需的席噩,因?yàn)樗仨毷锹窂降囊徊糠帧?# 所以班缰,你應(yīng)該在聲明時(shí)使用 ... 將其標(biāo)記為必需參數(shù)。
# 然而,即使你使用 None 聲明路徑參數(shù)或設(shè)置一個(gè)其他默認(rèn)值也不會(huì)有任何影響溉旋,它依然會(huì)是必需參數(shù)挂滓。
# sla_id: str = Path(None, description="SLA的id", example="100191918"))
# 數(shù)值校驗(yàn)
# gt:大于(greater than)
# le:小于等于(less than or equal)
# item_id: int = Path(..., title="The ID of the item to get", gt=0, le=1000),
14.請(qǐng)求體--多個(gè)參數(shù):
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
這里的 embed 參數(shù)為true時(shí)候, 將原本的請(qǐng)求體嵌入到一個(gè)鍵中岖食。
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
而不是:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
15.請(qǐng)求體 - 字段(Pydantic 的 Field)
與使用 Query莹妒、Path 和 Body 在路徑操作函數(shù)中聲明額外的校驗(yàn)和元數(shù)據(jù)的方式相同名船,
你可以使用 Pydantic 的 Field 在 Pydantic 模型內(nèi)部聲明校驗(yàn)和元數(shù)據(jù)。
Field 的工作方式和 Query旨怠、Path 和 Body 相同渠驼,包括它們的參數(shù)等等也完全相同。
16.請(qǐng)求體--嵌套模型
from pydantic import BaseModel, HttpUrl
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: Set[str] = set()
image: Optional[Image] = None
17.模式的額外信息
class Config:
schema_extra
聲明您的應(yīng)用可以接收的數(shù)據(jù)示例鉴腻。
同樣的方法迷扇,你可以添加你自己的額外信息,這些信息將被添加到每個(gè)模型的JSON模式中爽哎,例如定制前端用戶界面蜓席,等等。
18.cookie參數(shù)
- Cookie 倦青、Path 瓮床、Query是兄弟類,它們都繼承自公共的 Param 類
- async def read_items(ads_id: Optional[str] = Cookie(None)):
19.Header 參數(shù)
token=Header(..., alias="X-Auth-Token", title="X-Auth-Token", description="請(qǐng)求token"),
不用擔(dān)心變量中的下劃線产镐,F(xiàn)astAPI 會(huì)負(fù)責(zé)轉(zhuǎn)換它們隘庄。
21.響應(yīng)模型
在下面的任意的路徑操作中使用 response_model 參數(shù)來(lái)聲明用于響應(yīng)的模型:
@app.get()
@app.post()
@app.put()
@app.delete()
- response_model是「裝飾器」方法(get,post 等)的一個(gè)參數(shù)癣亚。不像之前的所有參數(shù)和請(qǐng)求體丑掺,它不屬于路徑操作函數(shù)。
例子:
@api.post(
"/restores/{copy_id}/action/download",
status_code=200,
tags=API_TAG,
description="Download API",
summary="download",
response_model=DownloadResponseSchema
)
22.響應(yīng)狀態(tài)碼
@app.post("/items/", status_code=201)
會(huì)在交互式文檔中展示返回在這里定義的狀態(tài)碼
23.表單數(shù)據(jù) Form
24.文件上傳
from fastapi import FastAPI, File, UploadFile
24.請(qǐng)求表格和文件
async def create_file(
file: bytes = File(...), fileb: UploadFile = File(...), token: str = Form(...)
):
當(dāng)您需要在同一請(qǐng)求中接收數(shù)據(jù)和文件時(shí)File述雾,F(xiàn)orm一起使用和街州。
25.請(qǐng)注意,response_description特指響應(yīng)玻孟,description泛指路徑操作唆缴。
description可以使用長(zhǎng)字符串或者多行文本。用于docs中api接口描述;參數(shù)response_description用于響應(yīng)描述黍翎。面徽。
26.tags 參數(shù):
你可以給路徑操作(post, put, get, delete)函數(shù)添加標(biāo)記,通過(guò)tags參數(shù)匣掸,參數(shù)類型可以是list或者str(一般是一個(gè)str):
主要作用就是在docs交互文檔中進(jìn)行 模塊之間的分割,mysql模塊, filesets 模塊
27.總結(jié)(summary)和描述(description)
28.Json兼容(將對(duì)象轉(zhuǎn)化為json)
from typing import Optional
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
class Item(BaseModel):
title: str
timestamp: str
description: Optional[str] = None
item = Item(title='nanfanfa',timestamp="2021.6.21")
json_compatible_item_data = jsonable_encoder(item)
print(json_compatible_item_data) # {'title': 'nanfanfa', 'timestamp': '2021.6.21', 'description': None}
print(json_compatible_item_data) # {'title': 'nanfanfa', 'timestamp': '2021.6.21', 'description': None}
if __name__ == '__main__':
uvicorn.run(app=app, host="10.148.228.113", port=65500, workers=1)