You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI中如何用include_in_schema实现条件路由隐藏多文档接口

问题

我通过挂载子应用在FastAPI中实现了两个Swagger文档:内部开发者用的/docs,外部客户用的/external_API/docs,二者共享同一路由router。我想仅在/external_API/docs里隐藏部分接口(比如/admin_something),/docs则显示全部接口。已知用include_in_schema=False能隐藏路由,但需要实现条件控制:访问外部文档时隐藏指定接口,访问内部文档时显示全部。我试过用判断root_path的自定义函数结合include_in_schema,但没成功,求可行的实现方案。


现有代码

main.py

from fastapi import FastAPI
from route import router as users_router

app = FastAPI() # 仅面向内部开发者的Swagger文档
app.include_router(users_router)

externalAPI = FastAPI() # 仅面向外部客户的Swagger文档
externalAPI.include_router(users_router)

# 将子应用挂载到主应用
app.mount("/external_API", externalAPI)

route.py

from fastapi import APIRouter

router = APIRouter()

@router.get('/admin_something', include_in_schema=True)
def route_admin_use_only():
   ...

@router.get('/user_something', include_in_schema=True)
def route_public_use():
   ...

尝试过的自定义函数(未成功)

def only_internal(request : Request):
    """
    当root_path为空时返回True(表示显示所有路由)
    """
    root_path = request.scope.get("root_path")
    if not root_path == "":
        return False
    return True

未成功的应用方式

# 期望访问"/external_API/docs"时隐藏该接口
@router.get('/admin_something', include_in_schema=only_internal)
def route_admin_use_only():
   ...

# 期望该接口始终可见
@router.get('/user_something', include_in_schema=Depends(only_internal))
def route_public_use():
   ...

可行实现方案

下面提供三种不同场景的解决方案,按需选择:

方案1:挂载时动态过滤接口(无需修改原路由)

核心是给外部应用复制一份路由,然后修改指定接口的include_in_schema属性,再挂载到外部应用上:

from fastapi import FastAPI
from route import router as base_router

# 内部应用:显示全部接口
app = FastAPI()
app.include_router(base_router)

# 外部应用:复制路由并隐藏指定接口
externalAPI = FastAPI()
# 复制基础路由的配置
external_router = base_router.__class__(prefix=base_router.prefix, tags=base_router.tags)

for route in base_router.routes:
    # 匹配需要隐藏的接口路径
    if route.path == "/admin_something":
        route.include_in_schema = False
    external_router.routes.append(route)

externalAPI.include_router(external_router)
app.mount("/external_API", externalAPI)

方案2:自定义OpenAPI文档生成逻辑(动态过滤)

直接修改外部应用的OpenAPI文档生成逻辑,在生成Swagger时删除指定接口:

from fastapi import FastAPI, Request
from route import router as users_router

app = FastAPI()
app.include_router(users_router)

externalAPI = FastAPI()
externalAPI.include_router(users_router)

# 自定义外部应用的OpenAPI生成函数
def custom_openapi():
    if externalAPI.openapi_schema:
        return externalAPI.openapi_schema
    # 生成原始OpenAPI结构
    openapi_schema = externalAPI.openapi()
    # 过滤掉需要隐藏的接口路径
    paths_to_remove = [path for path in openapi_schema["paths"] if "/admin_something" in path]
    for path in paths_to_remove:
        del openapi_schema["paths"][path]
    externalAPI.openapi_schema = openapi_schema
    return openapi_schema

externalAPI.openapi = custom_openapi
app.mount("/external_API", externalAPI)

方案3:拆分路由(最直观易维护)

把内部专用接口和公共接口拆分到不同的APIRouter中,内部应用挂载两个路由,外部应用只挂载公共路由:

修改后的route.py

from fastapi import APIRouter

# 公共路由:内部、外部均可见
public_router = APIRouter()

@public_router.get('/user_something', include_in_schema=True)
def route_public_use():
   ...

# 内部专用路由:仅内部可见
internal_router = APIRouter()

@internal_router.get('/admin_something', include_in_schema=True)
def route_admin_use_only():
   ...

修改后的main.py

from fastapi import FastAPI
from route import public_router, internal_router

# 内部应用:挂载公共+内部路由
app = FastAPI()
app.include_router(public_router)
app.include_router(internal_router)

# 外部应用:仅挂载公共路由
externalAPI = FastAPI()
externalAPI.include_router(public_router)

app.mount("/external_API", externalAPI)

内容的提问来源于stack exchange,提问作者MyHeadOverflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:12:47