fastapi是python的一個高性能web框架。它有着非常高的性能,與nodejs和go相當,和開發迅速等特點。
一、安裝
pip install fastapi
pip install uvicorn
二、例子
# main.py
from fastapi import FastAPI # 導入FastAPI import uvicorn app = FastAPI() # 創建一個app實例 @app.get("/") # 編寫一個路徑操作裝飾器 async def root(): # 編寫一個路徑操作函數 return {"你好!": "朋友。"} if __name__ == '__main__': uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)
注意:
- main:表示app所在的文件名
- app:表示fastapi的實例
- reload、debug:表示可以自動重啟
三、運行
uvicorn main:app --reload
注意pycharm里面快捷啟動—>右鍵run
四、路由
路由方法有 GET, POST, PUT, PATCH, DELETE 和 OPTIONS:
@app.post("/") @app.put("/") @app.delete("/") @app.get("/") @app.options("/") @app.head("/") @app.patch("/") @app.trace("/") async def root(): return {"message": "Hello World"}
五、動態路由獲取參數
@app.get("/items/{item_id}") # 路徑中的item_id將會被解析,傳遞給方法中的item_id。 async def read_item(item_id): return {"item_id": item_id}
六、在方法中定義參數類型
@app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}
當參數item_id是非數字,將報如下錯誤:
{ "detail": [ { "loc": [ "path", "item_id" ], "msg": "value is not a valid integer", "type": "type_error.integer" } ] }
所有的數據類型驗證,都是通過Pydantic完成的。
七、預定義路由參數
class ModelName(str, Enum): alexnet = "alexnet" resnet = "resnet" lenet = "lenet" @app.get("/model/{model_name}") async def get_model(model_name: ModelName): if model_name == ModelName.alexnet: return {"model_name": model_name, "message": "Deep Learning FTW!"} if model_name.value == "lenet": return {"model_name": model_name, "message": "LeCNN all the images"} return {"model_name": model_name, "message": "Have some residuals"}
八、路徑參數
想接收一個路徑參數,它本身就是一個路徑,就像/files/{file_path},而這個file_path是home/johndoe/myfile.txt時,可以寫成/files/{file_path:path}:
@app.get("/files/{file_path:path}") async def read_user_me(file_path: str): return {"file_path": file_path}
OpenAPI本身不支持在路徑參數包含路徑,但是可以當作Starlette內部的一個使用方法。
九、路由覆蓋問題
@app.get("/users/me") async def read_user_me(): return {"user_id": "the current user"} @app.get("/users/{user_id}") async def read_user(user_id: str): return {"被優先匹配到:": user_id}
當user_id=me時,路由@app.get("/users/me")會被路由@app.get("/users/{user_id}")覆蓋。
十、獲取查詢參數
@app.get("/items/") async def read_item(skip: int = 0, limit: int = 10): return skip + limit
請求http://127.0.0.1:8000/items/?skip=0&limit=2,將返回2.
請求http://127.0.0.1:8000/items/,將返回10,因為在函數內定義了默認值。
十一、多路徑和查詢參數
多路徑和查詢參數就是URL上包含了有動態的參數(動態路由),還有需要通過&分隔符提交的參數。
# http://127.0.0.1:8000/users/123456/items/items_xinxiid/?q=assa&short=True
@app.get("/users/{user_id}/items/{item_id}") async def read_user_item(user_id: int, item_id: str, q: str = None, short: bool = False): item = {"item_id": item_id, "owner_id": user_id} if q: item.update({"q": q}) if not short: item.update( {"description": "This is an amazing item that has a long description"} ) return item
注意:查詢參數如果設置了默認值,則是可選參數。
十二、使用Optional定義查詢參數的類型
from typing import Optional @app.get("/items/{item_id}") async def read_user_item(item_id: str, limit: Optional[int] = None): item = {"item_id": item_id, "limit": limit} return item
十三、Query參數
以前通常是使用wtform來定義提交的字段信息的類似或可選或長度類型。在Fastapi里面,我們是通過: from fastapi import FastAPI, Query 中的Query來定義:
from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") async def read_items(q: str = Query(None, min_length=3,max_length=50),regex="^fixedquery$"): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) return results
十四、Query參數多值列表
# http://127.0.0.1:8000/items/?q=foo&q=bar from typing import List from fastapi import FastAPI, Query app = FastAPI() @app.get("/items/") async def read_items(q: List[str] = Query(["foo", "bar"])): # <!--也可以使用list直接代替List[str]:--> query_items = {"q": q} return query_items
訪問 http://127.0.0.1:8000/items/ 返回 {"q":["foo","bar"]}
訪問 http://127.0.0.1:8000/items/?q=123&q=456 返回 {"q":["123","456"]}
十五、Path模塊
Fastapi自帶的Path也可以對參數進行校驗。
from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items(q: str, item_id: int = Path(..., title="The ID of the item to get")): results = {"item_id": item_id} if q: results.update({"q": q}) return results
對路徑參數做大於或等於操作,路徑參數的值必須不小於ge的值:
from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items(*, item_id: int = Path(..., title="The ID of the item to get", ge=1), q: str ): results = {"item_id": item_id} if q: results.update({"q": q}) return results
十六、多個Request Body的提交
更復雜的業務其實會存在多體的Boay的提交,
結束!