FastAPI教程 更大的應(yīng)用 - 多個(gè)文件

2021-11-03 11:29 更新

如果你正在開發(fā)一個(gè)應(yīng)用程序或 Web API,很少會(huì)將所有的內(nèi)容都放在一個(gè)文件中。

FastAPI 提供了一個(gè)方便的工具,可以在保持所有靈活性的同時(shí)構(gòu)建你的應(yīng)用程序。

Info

如果你來自 Flask,那這將相當(dāng)于 Flask 的 Blueprints。

一個(gè)文件結(jié)構(gòu)示例

假設(shè)你的文件結(jié)構(gòu)如下:

.
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │   ├── __init__.py
│   │   ├── items.py
│   │   └── users.py
│   └── internal
│       ├── __init__.py
│       └── admin.py

Tip

上面有幾個(gè) __init__.py 文件:每個(gè)目錄或子目錄中都有一個(gè)。

這就是能將代碼從一個(gè)文件導(dǎo)入到另一個(gè)文件的原因。

例如,在 app/main.py 中,你可以有如下一行:

from app.routers import items
  • app 目錄包含了所有內(nèi)容。并且它有一個(gè)空文件 app/__init__.py,因此它是一個(gè)「Python 包」(「Python 模塊」的集合):app。
  • 它包含一個(gè) app/main.py 文件。由于它位于一個(gè) Python 包(一個(gè)包含 __init__.py 文件的目錄)中,因此它是該包的一個(gè)「模塊」:app.main。
  • 還有一個(gè) app/dependencies.py 文件,就像 app/main.py 一樣,它是一個(gè)「模塊」:app.dependencies。
  • 有一個(gè)子目錄 app/routers/ 包含另一個(gè) __init__.py 文件,因此它是一個(gè)「Python 子包」:app.routers。
  • 文件 app/routers/items.py 位于 app/routers/ 包中,因此它是一個(gè)子模塊:app.routers.items。
  • 同樣適用于 app/routers/users.py,它是另一個(gè)子模塊:app.routers.users。
  • 還有一個(gè)子目錄 app/internal/ 包含另一個(gè) __init__.py 文件,因此它是又一個(gè)「Python 子包」:app.internal。
  • app/internal/admin.py 是另一個(gè)子模塊:app.internal.admin。

帶有注釋的同一文件結(jié)構(gòu):

.
├── app                  # 「app」是一個(gè) Python 包
│   ├── __init__.py      # 這個(gè)文件使「app」成為一個(gè) Python 包
│   ├── main.py          # 「main」模塊,例如 import app.main
│   ├── dependencies.py  # 「dependencies」模塊,例如 import app.dependencies
│   └── routers          # 「routers」是一個(gè)「Python 子包」
│   │   ├── __init__.py  # 使「routers」成為一個(gè)「Python 子包」
│   │   ├── items.py     # 「items」子模塊,例如 import app.routers.items
│   │   └── users.py     # 「users」子模塊,例如 import app.routers.users
│   └── internal         # 「internal」是一個(gè)「Python 子包」
│       ├── __init__.py  # 使「internal」成為一個(gè)「Python 子包」
│       └── admin.py     # 「admin」子模塊,例如 import app.internal.admin

APIRouter

假設(shè)專門用于處理用戶邏輯的文件是位于 /app/routers/users.py 的子模塊。

你希望將與用戶相關(guān)的路徑操作與其他代碼分開,以使其井井有條。

但它仍然是同一 FastAPI 應(yīng)用程序/web API 的一部分(它是同一「Python 包」的一部分)。

你可以使用 APIRouter 為該模塊創(chuàng)建路徑操作。

導(dǎo)入 APIRouter

你可以導(dǎo)入它并通過與 FastAPI 類相同的方式創(chuàng)建一個(gè)「實(shí)例」:

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}

使用 APIRouter 的路徑操作

然后你可以使用它來聲明路徑操作。

使用方式與 FastAPI 類相同:

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}

你可以將 APIRouter 視為一個(gè)「迷你 FastAPI」類。

所有相同的選項(xiàng)都得到支持。

所有相同的 parameters、responses、dependencies、tags 等等。

Tip

在此示例中,該變量被命名為 router,但你可以根據(jù)你的想法自由命名。

我們將在主 FastAPI 應(yīng)用中包含該 APIRouter,但首先,讓我們來看看依賴項(xiàng)和另一個(gè) APIRouter。

依賴項(xiàng)

我們了解到我們將需要一些在應(yīng)用程序的好幾個(gè)地方所使用的依賴項(xiàng)。

因此,我們將它們放在它們自己的 dependencies 模塊(app/dependencies.py)中。

現(xiàn)在我們將使用一個(gè)簡(jiǎn)單的依賴項(xiàng)來讀取一個(gè)自定義的 X-Token 請(qǐng)求首部:

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")

Tip

我們正在使用虛構(gòu)的請(qǐng)求首部來簡(jiǎn)化此示例。

但在實(shí)際情況下,使用集成的安全性實(shí)用工具會(huì)得到更好的效果。

其他使用 APIRouter 的模塊

假設(shè)你在位于 app/routers/items.py 的模塊中還有專門用于處理應(yīng)用程序中「項(xiàng)目」的端點(diǎn)。

你具有以下路徑操作:

  • /items/
  • /items/{item_id}

這和 app/routers/users.py 的結(jié)構(gòu)完全相同。

但是我們想變得更聰明并簡(jiǎn)化一些代碼。

我們知道此模塊中的所有路徑操作都有相同的:

  • 路徑 prefix:/items。
  • tags:(僅有一個(gè) items 標(biāo)簽)。
  • 額外的 responses。
  • dependencies:它們都需要我們創(chuàng)建的 X-Token 依賴項(xiàng)。

因此,我們可以將其添加到 APIRouter 中,而不是將其添加到每個(gè)路徑操作中。

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"}},
)


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"}

由于每個(gè)路徑操作的路徑都必須以 / 開頭,例如:

@router.get("/{item_id}")
async def read_item(item_id: str):
    ...

...前綴不能以 / 作為結(jié)尾。

因此,本例中的前綴為 /items。

我們還可以添加一個(gè) tags 列表和額外的 responses 列表,這些參數(shù)將應(yīng)用于此路由器中包含的所有路徑操作。

我們可以添加一個(gè) dependencies 列表,這些依賴項(xiàng)將被添加到路由器中的所有路徑操作中,并將針對(duì)向它們發(fā)起的每個(gè)請(qǐng)求執(zhí)行/解決。

Tip

請(qǐng)注意,和路徑操作裝飾器中的依賴項(xiàng)很類似,沒有值會(huì)被傳遞給你的路徑操作函數(shù)。

最終結(jié)果是項(xiàng)目相關(guān)的路徑現(xiàn)在為:

  • /items/
  • /items/{item_id}

...如我們所愿。

  • 它們將被標(biāo)記為僅包含單個(gè)字符串 "items" 的標(biāo)簽列表。這些「標(biāo)簽」對(duì)于自動(dòng)化交互式文檔系統(tǒng)(使用 OpenAPI)特別有用。
  • 所有的路徑操作都將包含預(yù)定義的 responses。
  • 所有的這些路徑操作都將在自身之前計(jì)算/執(zhí)行 dependencies 列表。如果你還在一個(gè)具體的路徑操作中聲明了依賴項(xiàng),它們也會(huì)被執(zhí)行。路由器的依賴項(xiàng)最先執(zhí)行,然后是裝飾器中的 dependencies,再然后是普通的參數(shù)依賴項(xiàng)。你還可以添加具有 scopes 的 Security 依賴項(xiàng)。

Tip

在 APIRouter中具有 dependencies 可以用來,例如,對(duì)一整組的路徑操作要求身份認(rèn)證。即使這些依賴項(xiàng)并沒有分別添加到每個(gè)路徑操作中。

Check

prefix、tags、responses 以及 dependencies 參數(shù)只是(和其他很多情況一樣)FastAPI 的一個(gè)用于幫助你避免代碼重復(fù)的功能。

導(dǎo)入依賴項(xiàng)

這些代碼位于 app.routers.items 模塊,app/routers/items.py 文件中。

我們需要從 app.dependencies 模塊即 app/dependencies.py 文件中獲取依賴函數(shù)。

因此,我們通過 .. 對(duì)依賴項(xiàng)使用了相對(duì)導(dǎo)入:

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"}},
)


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"}

相對(duì)導(dǎo)入如何工作

Tip

如果你完全了解導(dǎo)入的工作原理,請(qǐng)從下面的下一部分繼續(xù)。

一個(gè)單點(diǎn) .,例如:

from .dependencies import get_token_header

表示:

  • 從該模塊(app/routers/items.py 文件)所在的同一個(gè)包(app/routers/ 目錄)開始...
  • 找到 dependencies 模塊(一個(gè)位于 app/routers/dependencies.py 的虛構(gòu)文件)...
  • 然后從中導(dǎo)入函數(shù) get_token_header。

但是該文件并不存在,我們的依賴項(xiàng)位于 app/dependencies.py 文件中。

請(qǐng)記住我們的程序/文件結(jié)構(gòu)是怎樣的:

兩個(gè)點(diǎn) ..,例如:

from ..dependencies import get_token_header

表示:

  • 從該模塊(app/routers/items.py 文件)所在的同一個(gè)包(app/routers/ 目錄)開始...
  • 跳轉(zhuǎn)到其父包(app/ 目錄)...
  • 在該父包中,找到 dependencies 模塊(位于 app/dependencies.py 的文件)...
  • 然后從中導(dǎo)入函數(shù) get_token_header。

正常工作了!????

同樣,如果我們使用了三個(gè)點(diǎn) ...,例如:

from ...dependencies import get_token_header

那將意味著:

  • 從該模塊(app/routers/items.py 文件)所在的同一個(gè)包(app/routers/ 目錄)開始...
  • 跳轉(zhuǎn)到其父包(app/ 目錄)...
  • 然后跳轉(zhuǎn)到該包的父包(該父包并不存在,app 已經(jīng)是最頂層的包 ????)...
  • 在該父包中,找到 dependencies 模塊(位于 app/ 更上一級(jí)目錄中的 dependencies.py 文件)...
  • 然后從中導(dǎo)入函數(shù) get_token_header。

這將引用 app/ 的往上一級(jí),帶有其自己的 __init __.py 等文件的某個(gè)包。但是我們并沒有這個(gè)包。因此,這將在我們的示例中引發(fā)錯(cuò)誤。????

但是現(xiàn)在你知道了它的工作原理,因此無論它們多么復(fù)雜,你都可以在自己的應(yīng)用程序中使用相對(duì)導(dǎo)入。????

添加一些自定義的 tags、responses 和 dependencies

我們不打算在每個(gè)路徑操作中添加前綴 /items 或 tags =["items"],因?yàn)槲覀儗⑺鼈兲砑拥搅?nbsp;APIRouter 中。

但是我們?nèi)匀豢梢蕴砑痈鄬?huì)應(yīng)用于特定的路徑操作的 tags,以及一些特定于該路徑操作的額外 responses:

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"}},
)


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"}

Tip

最后的這個(gè)路徑操作將包含標(biāo)簽的組合:["items","custom"]。

并且在文檔中也會(huì)有兩個(gè)響應(yīng),一個(gè)用于 404,一個(gè)用于 403。

FastAPI 主體

現(xiàn)在,讓我們來看看位于 app/main.py 的模塊。

在這里你導(dǎo)入并使用 FastAPI 類。

這將是你的應(yīng)用程序中將所有內(nèi)容聯(lián)結(jié)在一起的主文件。

并且由于你的大部分邏輯現(xiàn)在都存在于其自己的特定模塊中,因此主文件的內(nèi)容將非常簡(jiǎn)單。

導(dǎo)入 FastAPI

你可以像平常一樣導(dǎo)入并創(chuàng)建一個(gè) FastAPI 類。

我們甚至可以聲明全局依賴項(xiàng),它會(huì)和每個(gè) APIRouter 的依賴項(xiàng)組合在一起:

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(
    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!"}

導(dǎo)入 APIRouter

現(xiàn)在,我們導(dǎo)入具有 APIRouter 的其他子模塊:

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(
    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!"}

由于文件 app/routers/users.py 和 app/routers/items.py 是同一 Python 包 app 一個(gè)部分的子模塊,因此我們可以使用單個(gè)點(diǎn) . 通過「相對(duì)導(dǎo)入」來導(dǎo)入它們。

導(dǎo)入是如何工作的

這段代碼:

from .routers import items, users

表示:

  • 從該模塊(app/main.py 文件)所在的同一個(gè)包(app/ 目錄)開始...
  • 尋找 routers 子包(位于 app/routers/ 的目錄)...
  • 從該包中,導(dǎo)入子模塊 items (位于 app/routers/items.py 的文件) 以及 users (位于 app/routers/users.py 的文件)...

items 模塊將具有一個(gè) router 變量(items.router)。這與我們?cè)?nbsp;app/routers/items.py 文件中創(chuàng)建的變量相同,它是一個(gè) APIRouter 對(duì)象。

然后我們對(duì) users 模塊進(jìn)行相同的操作。

我們也可以像這樣導(dǎo)入它們:

from app.routers import items, users

Info

第一個(gè)版本是「相對(duì)導(dǎo)入」:

from .routers import items, users

第二個(gè)版本是「絕對(duì)導(dǎo)入」:

from app.routers import items, users

要了解有關(guān) Python 包和模塊的更多信息,請(qǐng)查閱關(guān)于 Modules 的 Python 官方文檔。

避免名稱沖突

我們將直接導(dǎo)入 items 子模塊,而不是僅導(dǎo)入其 router 變量。

這是因?yàn)槲覀冊(cè)?nbsp;users 子模塊中也有另一個(gè)名為 router 的變量。

如果我們一個(gè)接一個(gè)地導(dǎo)入,例如:

from .routers.items import router
from .routers.users import router

來自 users 的 router 將覆蓋來自 items 中的 router,我們將無法同時(shí)使用它們。

因此,為了能夠在同一個(gè)文件中使用它們,我們直接導(dǎo)入子模塊:

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(
    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!"}

包含 users 和 items 的 APIRouter

現(xiàn)在,讓我們來包含來自 users 和 items 子模塊的 router。

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(
    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!"}

Info

users.router 包含了 app/routers/users.py 文件中的 APIRouter。

items.router 包含了 app/routers/items.py 文件中的 APIRouter。

使用 app.include_router(),我們可以將每個(gè) APIRouter 添加到主 FastAPI 應(yīng)用程序中。

它將包含來自該路由器的所有路由作為其一部分。

技術(shù)細(xì)節(jié)

實(shí)際上,它將在內(nèi)部為聲明在 APIRouter 中的每個(gè)路徑操作創(chuàng)建一個(gè)路徑操作。

所以,在幕后,它實(shí)際上會(huì)像所有的東西都是同一個(gè)應(yīng)用程序一樣工作。

Check

包含路由器時(shí),你不必?fù)?dān)心性能問題。

這將花費(fèi)幾微秒時(shí)間,并且只會(huì)在啟動(dòng)時(shí)發(fā)生。

因此,它不會(huì)影響性能。?

包含一個(gè)有自定義 prefix、tags、responses 和 dependencies 的 APIRouter

現(xiàn)在,假設(shè)你的組織為你提供了 app/internal/admin.py 文件。

它包含一個(gè)帶有一些由你的組織在多個(gè)項(xiàng)目之間共享的管理員路徑操作的 APIRouter。

對(duì)于此示例,它將非常簡(jiǎn)單。但是假設(shè)由于它是與組織中的其他項(xiàng)目所共享的,因此我們無法對(duì)其進(jìn)行修改,以及直接在 APIRouter 中添加 prefix、dependencies、tags 等:

from fastapi import APIRouter

router = APIRouter()


@router.post("/")
async def update_admin():
    return {"message": "Admin getting schwifty"}

但是我們?nèi)匀幌M诎?nbsp;APIRouter 時(shí)設(shè)置一個(gè)自定義的 prefix,以便其所有路徑操作以 /admin 開頭,我們希望使用本項(xiàng)目已經(jīng)有的 dependencies 保護(hù)它,并且我們希望它包含自定義的 tags 和 responses。

我們可以通過將這些參數(shù)傳遞給 app.include_router() 來完成所有的聲明,而不必修改原始的 APIRouter:

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(
    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!"}

這樣,原始的 APIRouter 將保持不變,因此我們?nèi)匀豢梢耘c組織中的其他項(xiàng)目共享相同的 app/internal/admin.py 文件。

結(jié)果是在我們的應(yīng)用程序中,來自 admin 模塊的每個(gè)路徑操作都將具有:

  • /admin 前綴 。
  • admin 標(biāo)簽。
  • get_token_header 依賴項(xiàng)。
  • 418 響應(yīng)。 ????

但這只會(huì)影響我們應(yīng)用中的 APIRouter,而不會(huì)影響使用它的任何其他代碼。

因此,舉例來說,其他項(xiàng)目能夠以不同的身份認(rèn)證方法使用相同的 APIRouter。

包含一個(gè)路徑操作

我們還可以直接將路徑操作添加到 FastAPI 應(yīng)用中。

這里我們這樣做了...只是為了表明我們可以做到????:

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(
    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!"}

它將與通過 app.include_router() 添加的所有其他路徑操作一起正常運(yùn)行。

特別的技術(shù)細(xì)節(jié)

注意:這是一個(gè)非常技術(shù)性的細(xì)節(jié),你也許可以直接跳過。

APIRouter 沒有被「掛載」,它們與應(yīng)用程序的其余部分沒有隔離。

這是因?yàn)槲覀兿胍?OpenAPI 模式和用戶界面中包含它們的路徑操作。

由于我們不能僅僅隔離它們并獨(dú)立于其余部分來「掛載」它們,因此路徑操作是被「克隆的」(重新創(chuàng)建),而不是直接包含。

查看自動(dòng)化的 API 文檔

現(xiàn)在,使用 app.main 模塊和 app 變量運(yùn)行 uvicorn:

uvicorn app.main:app --reload


INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)


然后打開位于 http://127.0.0.1:8000/docs 的文檔。

你將看到使用了正確路徑(和前綴)和正確標(biāo)簽的自動(dòng)化 API 文檔,包括了來自所有子模塊的路徑:

多次使用不同的 prefix 包含同一個(gè)路由器

你也可以在同一路由器上使用不同的前綴來多次使用 .include_router()。

在有些場(chǎng)景這可能有用,例如以不同的前綴公開同一個(gè)的 API,比方說 /api/v1 和 /api/latest。

這是一個(gè)你可能并不真正需要的高級(jí)用法,但萬一你有需要了就能夠用上。

在另一個(gè) APIRouter 中包含一個(gè) APIRouter

與在 FastAPI 應(yīng)用程序中包含 APIRouter 的方式相同,你也可以在另一個(gè) APIRouter 中包含 APIRouter,通過:

router.include_router(other_router)

請(qǐng)確保在你將 router 包含到 FastAPI 應(yīng)用程序之前進(jìn)行此操作,以便 other_router 中的路徑操作也能被包含進(jìn)來。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)