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

动态添加FastAPI端点时如何更新Swagger UI?

FastAPI动态端点同步更新Swagger UI的实现方案

核心原理:触发OpenAPI Schema重新生成

FastAPI的Swagger UI依赖缓存的OpenAPI Schema,要更新Swagger必须强制重新生成该Schema:

  • 执行app.openapi_schema = None清除缓存的Schema
  • 调用app.setup()重新收集所有路由并生成新的Schema

这两步能实现刷新Swagger页面时看到更新后的端点,若需实现前端自动强制刷新,则需额外处理。


1. 基础版:手动刷新页面生效的实现

在你现有代码基础上,给增删端点的逻辑加入Schema重置步骤即可:

import fastapi
import uvicorn
from uvicorn.config import LOGGING_CONFIG

app = fastapi.FastAPI()

def update_swagger():
    # 清除缓存的OpenAPI Schema
    app.openapi_schema = None
    # 重新初始化路由收集
    app.setup()

@app.get("/add")
async def add(name: str):
    async def dynamic_controller():
        return f"dynamic: {name}"
    app.add_api_route(f"/dyn/{name}", dynamic_controller, methods=["GET"])
    update_swagger()  # 新增Schema更新逻辑
    return "ok"

def route_matches(route, name):
    return route.path_format == f"/dyn/{name}"

@app.get("/remove")
async def remove(name: str):
    for i, r in enumerate(app.router.routes):
        if route_matches(r, name):
            del app.router.routes[i]
            update_swagger()  # 新增Schema更新逻辑
            return "ok"
    return "not found"

def main():
    uvicorn.run("dynamic_router:app", host="0.0.0.0", workers=1, log_config=LOGGING_CONFIG, port=5000)

if __name__ == "__main__":
    main()

修改后,每次增删端点后刷新Swagger UI(默认路径/docs),即可看到最新的端点列表。


2. 进阶版:实现Swagger UI自动强制刷新

要让Swagger页面自动感知端点变化并刷新,可通过以下两种方案实现:

方案A:WebSocket推送更新通知

后端新增WebSocket接口,端点变化时向前端推送刷新信号,前端Swagger页面监听信号后自动刷新:

# 在原代码中添加WebSocket相关逻辑
from fastapi import WebSocket, WebSocketDisconnect

active_connections = []

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    active_connections.append(websocket)
    try:
        while True:
            await websocket.receive_text()
    except WebSocketDisconnect:
        active_connections.remove(websocket)

# 修改update_swagger函数,添加推送逻辑
async def update_swagger():
    app.openapi_schema = None
    app.setup()
    # 向所有连接的WebSocket客户端发送刷新指令
    for connection in active_connections:
        await connection.send_text("refresh_swagger")

然后自定义FastAPI的Swagger文档模板,在模板中加入WebSocket监听代码,收到信号时调用location.reload()刷新页面。

方案B:定时轮询后端端点列表

若不想使用WebSocket,可让前端定时请求后端的端点列表接口,对比本地缓存的端点信息,发现变化时自动刷新:

  1. 后端新增接口返回当前所有动态端点:
@app.get("/dyn/routes")
async def get_dynamic_routes():
    return {"routes": [r.path_format for r in app.router.routes if r.path_format.startswith("/dyn/")]}
  1. 自定义Swagger模板,添加JavaScript定时轮询逻辑(比如每5秒请求一次/dyn/routes),对比前后结果,若不同则触发页面刷新。

3. Router机制下的适配说明

你在编辑2中使用APIRouter的方案逻辑是正确的,若未看到Swagger更新,可能是浏览器缓存了旧的OpenAPI Schema,此时可通过以下方式验证:

  • 强制刷新浏览器(Ctrl+F5)
  • 点击Swagger页面右上角的「Reload」按钮

该方案中update_swagger()函数的逻辑完全有效,app.setup()会重新收集所有已注册的Router路由信息。


关键注意事项

  • 必须使用单worker模式(代码中workers=1),多worker环境下每个worker的路由状态独立,动态增删仅会影响当前worker
  • 若需Swagger正确展示动态端点的参数、响应模型等信息,需在调用app.add_api_route()时完整定义这些元数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:45:08