以往的文件都是將對外接口寫在一個文件里邊,而作為應用來說,接口是不可避免分散到多個文件中的,比如某文件負責注冊登錄模塊,某文件負責內(nèi)管模塊,某文件負責業(yè)務模塊等。FastAPI 也提供了APIRouter 這一工具來進行靈活構(gòu)建應用,本文將是它的示例。
目錄
1?APIRouter
1.1?APIRouter 使用
1.2 其他模塊的引入
2 app 項目示例
2.1 文件結(jié)構(gòu)
2.2 其他 文件
2.3 main 文件
2.4 API 文檔
???源碼地址:
https://gitee.com/yinyuu/fast-api_study_yinyu
1?APIRouter
大家可以看到,前邊的示例均是以?app = FastAPI() 作為路由,但是它只適合小項目,如果接口按模塊進行劃分就不滿足了。而?APIRouter 正實現(xiàn)了接口按模塊的功能,以使其井井有條。
1.1?APIRouter 使用
類似?app = FastAPI()
from fastapi import APIRouter #導入 APIRouter
router = APIRouter()
@router.get("/users/", tags=["users"])
async def read_users():
return [{"username": "Rick"}, {"username": "Morty"}]
可以將 APIRouter 視為一個小號 FastAPI 類,所有相同的選項都得到支持,比如 parameters、responses、dependencies、tags 等等。
此示例中,該變量被命名為 router,但你可以根據(jù)你的想法自由命名。
1.2 其他模塊的引入
類似 FastAPI ,我們還可以通過 prefix、tags、dependencies 和 responses 等參數(shù)來減少重復代碼和增加效率。比如有兩個接口:
- /items/
- /items/{item_id}
他們的路徑前綴一樣,那么我們通過以下方式簡化代碼:
-
prefix:/items,前綴,不能以?
/
?作為結(jié)尾,不然回合路徑重合 - tags:items 標簽,主要在 api 文檔中用于分類
- responses:額外的響應模型,所有接口都將擁有
- dependencies:依賴,比如 get_token_header 依賴項。
from fastapi import APIRouter, Depends, HTTPException
from ..dependencies import get_token_header #通過 .. 對依賴項使用了相對導入,具體代碼可看第二章
router = APIRouter(
prefix="/items",
tags=["items"],
dependencies=[Depends(get_token_header)],
responses={404: {"description": "Not found"}},
)
@router.get("/")
async def read_items():
return fake_items_db
@router.get("/{item_id}")
async def read_item(item_id: str):
if item_id not in fake_items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
最終結(jié)果是項目相關(guān)的路徑現(xiàn)在為:
- /items/
- /items/{item_id}
2 app 項目示例
接下來以 app 項目為例,展示一下多文件應用的構(gòu)建。
2.1 文件結(jié)構(gòu)
???結(jié)構(gòu)如下:
app 目錄包含了所有內(nèi)容,他是一個?Python 包:
- app/main.py:main 模塊,也是項目的主文件,或者說啟動類
- app/dependencies.py:存放依賴項
-
app/routers/ :Python 子包:
- app/routers/items.py:存放 ietms 相關(guān)接口
- app/routers/users.py:存放 users?相關(guān)接口
-
app/internal/ :Python 子包:
- app/internal/admin.py:內(nèi)管相關(guān)接口
2.2 其他 文件
???dependencies.py
依賴項相關(guān)方法,驗證請求體和 token ~
from fastapi import Header, HTTPException
async def get_token_header(x_token: str = Header()):
if x_token != "fake-super-secret-token":
raise HTTPException(status_code=400, detail="X-Token header invalid")
async def get_query_token(token: str):
if token != "jessica":
raise HTTPException(status_code=400, detail="No Jessica token provided")
???items.py
from fastapi import APIRouter, Depends, HTTPException
from ..dependencies import get_token_header
router = APIRouter(
prefix="/items",
tags=["items"],
dependencies=[Depends(get_token_header)],
responses={404: {"description": "Not found111"}},
)
fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}
@router.get("/")
async def read_items():
return fake_items_db
@router.get("/{item_id}")
async def read_item(item_id: str):
if item_id not in fake_items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
@router.put(
"/{item_id}",
tags=["custom"],
responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):
if item_id != "plumbus":
raise HTTPException(
status_code=403, detail="You can only update the item: plumbus"
)
return {"item_id": item_id, "name": "The great Plumbus"}
???users.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/users/", tags=["users"])
async def read_users():
return [{"username": "Rick"}, {"username": "Morty"}]
@router.get("/users/me", tags=["users"])
async def read_user_me():
return {"username": "fakecurrentuser"}
@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):
return {"username": username}
???users.py
from fastapi import APIRouter
router = APIRouter()
@router.post("/")
async def update_admin():
return {"message": "Admin getting schwifty"}
以上接口文件均使用 APIRouter ,最后將調(diào)用給 main 文件以供匯總。
2.3 main 文件
這里你導入并使用 FastAPI 類,是應用程序中將所有內(nèi)容聯(lián)結(jié)在一起的主文件。?
from fastapi import Depends, FastAPI
from .dependencies import get_query_token, get_token_header
from .internal import admin
from .routers import items, users
app = FastAPI(dependencies=[Depends(get_query_token)])
app.include_router(users.router)
app.include_router(items.router)
app.include_router( #依舊可自定義參數(shù)
admin.router,
prefix="/admin",
tags=["admin"],
dependencies=[Depends(get_token_header)],
responses={418: {"description": "I'm a teapot"}},
)
@app.get("/")
async def root():
return {"message": "Hello Bigger Applications!"}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
???導入模塊
比如:
from .routers import items, users
- 這表示從該模塊(app/main.py 文件)所在的同一個包(app/ 目錄)
- 尋找 routers 子包(位于 app/routers/ 的目錄)...
- 從該包中,導入子模塊 items (位于 app/routers/items.py 的文件) 以及 users (位于 app/routers/users.py 的文件)...
items 模塊將具有一個 router 變量(items.router)。
相對導入:from .routers import items, users
絕對導入:from app.routers import items, users
???app.include_router
app.include_router(users.router)
app.include_router(items.router)
使用 app.include_router(),我們可以將每個 APIRouter 添加到主 FastAPI 應用程序中。 它將包含來自該路由器的所有路由作為其一部分。
官方:包含路由器時,你不必擔心性能問題。 這將花費幾微秒時間,并且只會在啟動時發(fā)生。 因此,它不會影響性能。?
2.4 API 文檔
啟動 main 文件,訪問?http://127.0.0.1:8000/docs,即可看到使用了正確路徑(和前綴)和正確標簽的自動化 API 文檔,包括了來自所有子模塊的路徑:
文章來源:http://www.zghlxwxcb.cn/news/detail-497742.html
由于 fastapi 內(nèi)置的接口文檔使用的外網(wǎng)的 cdn,所以可能導致頁面卡死,接口文檔顯示空白,解決辦法可參考:https://blog.csdn.net/m0_52726759/article/details/124854070。文章來源地址http://www.zghlxwxcb.cn/news/detail-497742.html
到了這里,關(guān)于【Python開發(fā)】FastAPI 11:構(gòu)建多文件應用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!