FastAPI 文档界面定制实战:全面掌握swagger_ui_parameters配置 Swagger UI
【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi
在 FastAPI 中,交互式 API 文档(默认挂在/docs)基于 Swagger UI 渲染。本篇指南以官方 How-To 文档 docs/en/docs/how-to/configure-swagger-ui.md(仓库中另含 印地语译文)为骨架,深入讲解如何通过swagger_ui_parameters参数传递配置字典,实现对 Swagger UI 的语法高亮、主题皮肤、默认参数覆盖乃至全量行为定制。读完本文,你将掌握两条配置入口、三类典型配置场景(关闭语法高亮、切换配色主题、覆盖内置默认参数),并理解 FastAPI 在源码层面对这些配置所做的 JSON 序列化与 HTML 安全转义处理。
配置入口:swagger_ui_parameters的两条通路
swagger_ui_parameters接收一个字典,其中的每一项配置都会被原样直通Swagger UI,而不是经过 FastAPI 的二次解释。官方文档明确了两个使用位置:
- 创建
FastAPI()应用对象时传入——这是最常用、最推荐的方式; - 调用
get_swagger_ui_html()函数时传入——适用于需要手工覆写文档 HTML 的场景。
从源码看,第一条通路的完整链路位于 fastapi/applications.py:FastAPI.__init__将swagger_ui_parameters: dict[str, Any] | None = None保存到self.swagger_ui_parameters(fastapi/applications.py);随后在setup()方法中注册/docs路由时(fastapi/applications.py),会把该字典转发给get_swagger_ui_html(..., swagger_ui_parameters=self.swagger_ui_parameters),最终拼进返回给浏览器的 HTML。
第二条通路直接命中核心实现 fastapi/openapi/docs.py 中的get_swagger_ui_html()。也就是说,两条入口殊途同归,最终都汇聚到同一个函数。
为何是 JSON?原文档特别强调:FastAPI 会把配置转换成JSON,因为 Swagger UI 本身运行在浏览器 JavaScript 环境中,只认 JSON 表达的对象。观察 docs.py 的生成循环可以印证这一点:
for key, value in current_swagger_ui_parameters.items(): html += f"{_html_safe_json(key)}: {_html_safe_json(jsonable_encoder(value))},\n"每个配置项都先经过jsonable_encoder处理成 JSON 兼容结构,再以 JSON 形式注入到页面<script>块里——所以 Python 的False会被序列化成 JavaScript 的false(小写),Python 字典会变成嵌套的 JS 对象。这正是下面各节中配置能生效的底层原因。
示例基线:一个可运行的最小应用
后续所有示例都基于docs_src/configure_swagger_ui/tutorial001_py310.py这类代码(完整可见 tutorial001_py310.py、tutorial002_py310.py、tutorial003_py310.py),结构如下:
from fastapi import FastAPI app = FastAPI(swagger_ui_parameters={"syntaxHighlight": False}) @app.get("/users/{username}") async def read_user(username: str): return {"message": f"Hello {username}"}启动应用后访问/docs,即可观察 Swagger UI 渲染结果随swagger_ui_parameters变化。
关闭语法高亮:syntaxHighlight: False
FastAPI 生成代码示例时默认开启语法高亮,界面效果可参考仓库内置截图 docs/en/docs/img/tutorial/extending-openapi/image02.png。
如果你希望关闭高亮以获得更素净的展示,只需把 Swagger UI 的syntaxHighlight配置设为False:
from fastapi import FastAPI app = FastAPI(swagger_ui_parameters={"syntaxHighlight": False})关闭后代码块不再着色,效果对比可参考 docs/en/docs/img/tutorial/extending-openapi/image03.png。仓库的自动化测试 test_tutorial001.py 会请求/docs并断言响应 HTML 中同时包含"syntaxHighlight": false(注意此时是 JSON 序列化后的小写false)以及若干默认参数,验证了关闭逻辑确实生效。
切换配色主题:嵌套参数syntaxHighlight.theme
原文档指出,设置主题时使用的 key 是"syntaxHighlight.theme"——中间带一个点号,表示它在 Swagger UI 配置对象里是一个嵌套路径。在 Python 代码中表达同一语义,就是把主题值放到嵌套字典里:
from fastapi import FastAPI app = FastAPI(swagger_ui_parameters={"syntaxHighlight": {"theme": "obsidian"}})这里把代码高亮主题切换为经典的深色主题obsidian,效果可见 docs/en/docs/img/tutorial/extending-openapi/image04.png。这一语法说明两点通用规律:
- Swagger UI 官方配置中任何带
.的"点号路径"参数,在 Python 侧都应写成嵌套字典; - 由于字典会被整体 JSON 序列化,嵌套结构能无损传递给浏览器端的 Swagger UI 对象。
覆盖 FastAPI 内置的默认参数
为让大多数场景开箱即用,FastAPI 在get_swagger_ui_html()里预置了一套默认配置。在 fastapi/openapi/docs.py 中可以看到swagger_ui_default_parameters的定义,共五项:
| 默认参数 | 默认值 | 含义 |
|---|---|---|
dom_id | "#swagger-ui" | Swagger UI 挂载的 DOM 节点选择器 |
layout | "BaseLayout" | 使用的布局组件 |
deepLinking | True | 是否允许 URL 深度链接到具体操作 |
showExtensions | True | 是否展示扩展字段 |
showCommonExtensions | True | 是否展示常见扩展字段 |
需要说明的是,原文档引用的是 docs.py 较旧版本的行区间,当前仓库中该常量定义在docs.py的第 22~37 行,内容与文档描述一致。合并逻辑位于 fastapi/openapi/docs.py:
current_swagger_ui_parameters = swagger_ui_default_parameters.copy() if swagger_ui_parameters: current_swagger_ui_parameters.update(swagger_ui_parameters)可见 FastAPI 采用"先复制默认值、再用你传入的字典覆盖"的策略——因此你只需在swagger_ui_parameters中给出想改的那一项,其余默认参数依然保留。
例如要关闭 URL 深度链接功能,把deepLinking覆盖为False即可:
from fastapi import FastAPI app = FastAPI(swagger_ui_parameters={"deepLinking": False})若想以默认参数为模板自行扩展,FastAPI 把常量swagger_ui_default_parameters作为公开对象导出,可直接from fastapi.openapi.docs import swagger_ui_default_parameters后.copy()一份再修改。从源码结构可以推断:它被设计成一个可复制的"模板字典",正如其 Doc 注释所写:"You can use it as a template to add any other configurations needed."
更多 Swagger UI 参数:按需透传
原文档明确指出:除上述演示外,Swagger UI 还支持大量其他官方配置项,FastAPI 的策略是不拦截、不透传无关参数、把字典整体交给 Swagger UI。因此任意官方支持的配置都可以按相同语法传入,例如(具体取值请以 Swagger UI 官方参数文档为准,它们都位于点号路径或嵌套对象中):
from fastapi import FastAPI app = FastAPI( swagger_ui_parameters={ "syntaxHighlight": {"theme": "obsidian"}, # 嵌套对象:点号路径写法 "docExpansion": "none", # 初始展开行为 "displayRequestDuration": True, # 展示请求耗时 "filter": True, # 顶部操作过滤框 "operationsSorter": "method", # 操作排序规则 "persistAuthorization": True, # 记住已授权的凭据 } )判断标准很简单:凡是 Swagger UI 官方接受的对象式(非函数式)配置,都可以写进这个字典,FastAPI 会负责完成 JSON 序列化与注入。需要留意的是字典的最终形态必须是 JSON 可序列化的(字符串、布尔、数字、数组、嵌套对象),函数等不可序列化的值无法通过此入口传递。
仅限 JavaScript 的配置:presets与覆写方案
Swagger UI 的部分配置项只能是 JavaScript 对象(典型例子是 JavaScript 函数),例如页面默认注入的presets。FastAPI 在生成 HTML 时固定写入以下代码(见 fastapi/openapi/docs.py):
presets: [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ],关键点在于:presets的值是JavaScript 对象,而非字符串,Python 无法把函数或运行时对象塞进swagger_ui_parameters字典,因此这类配置不能通过前述两种传参方式修改。
如果确实需要此类仅限 JavaScript 的配置,原文档给出的方案是:整体覆写 Swagger UI 的 path operation——也就是不依赖 FastAPI 自动生成的/docs页面,而是自行调用get_swagger_ui_html()(把swagger_ui_parameters、JavaScript/CSS 地址等作为参数),手动编写返回 HTML 中所需的任意 JavaScript。相关细节可继续阅读仓库中 Custom Docs UI Static Assets 相关文档 及get_swagger_ui_html的完整签名与参数说明(fastapi/openapi/docs.py)。
安全细节:配置注入前的 HTML 转义
参数直通浏览器的同时,FastAPI 也做了必要的安全防护。get_swagger_ui_html生成 HTML 时调用_html_safe_json()(定义于 fastapi/openapi/docs.py),它会先用json.dumps序列化,再把<、>、&分别转义为\u003c、\u003e、\u0026:
return ( json.dumps(value) .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("&", "\\u0026") )这是因为参数最终被嵌入页面<script>标签内部,若不转义,包含<img src=x onerror=...>之类内容的恶意配置值可能造成脚本注入(XSS)。仓库中 test_swagger_ui_escape.py 专门验证了这一点:当swagger_ui_parameters={"customKey": "<img src=x onerror=alert(1)>"}时,生成的响应中 HTML 特殊字符会被正确转义。init_oauth配置(同样进入 HTML)也使用相同的转义逻辑。
借助测试用例理解预期行为
仓库为本文三个教程示例都配备了测试,是理解配置最终形态的最佳佐证:
- test_tutorial001.py:断言
"syntaxHighlight": false(JSON 布尔值序列化)、默认配置项"dom_id": "#swagger-ui"、"layout": "BaseLayout"、"deepLinking": true等被保留,且presets内容原样存在; - test_tutorial002.py 与 test_tutorial003.py:分别对应主题配置与
deepLinking: False的覆盖场景。
测试同时验证了另一关键行为:传入的配置与默认配置是合并关系而非替换关系——自定义项出现的同时,五项默认参数依然完整保留在 HTML 中。这与前文 docs.py 中copy()+update()的合并逻辑一一对应。
小结
swagger_ui_parameters接受一个 JSON 可序列化的字典,可在FastAPI()构造或get_swagger_ui_html()调用时传入,最终注入/docs页面;- 配置项会被
jsonable_encoder转成 JSON 后交给 Swagger UI,因此带点号的嵌套路径(如syntaxHighlight.theme)需写成嵌套字典; - FastAPI 内置
dom_id、layout、deepLinking、showExtensions、showCommonExtensions五项默认参数,用户字典会与它们浅合并、逐键覆盖; - 函数等 JavaScript-only 配置(如
presets)无法通过 Python 字典传递,需覆写整个 Swagger UI path operation 手工编写; - 所有注入值均经过 HTML 转义,防止配置内容引发脚本注入。
【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考