首页
/ Scalar FastAPI 集成实战:scalar-fastapi 插件完整配置参考与源码实现原理

Scalar FastAPI 集成实战:scalar-fastapi 插件完整配置参考与源码实现原理

2026-09-13 16:35:41作者:尤辰城Agatha

本文以 Scalar 官方的 FastAPI 集成文档为主线,讲解如何用 scalar-fastapi 包在 FastAPI 应用中一行代码挂载交互式 OpenAPI 文档(Scalar API Reference),覆盖 add_scalar_reference 快速接入、自定义路由、多 OpenAPI 源(sources)、直接传入 OpenAPI 内容、Agent AI 聊天等用法,并完整整理全部配置参数的默认值与取值;随后结合仓库内 插件源码测试用例,剖析配置项如何被序列化进 Scalar.createApiReference、枚举与纯字符串为何可以互换、以及标题转义与 </script> 逃逸防护的实现细节。读完你可以直接在 FastAPI 项目中落地一套可定制、可多源、可关闭遥测与 Agent 的 API 文档方案。

FastAPI 集成渲染出的 Scalar API Reference 界面截图

一、安装

Scalar 的 FastAPI 插件以 PyPI 包 scalar-fastapi 发布(MIT 许可,要求 Python ≥ 3.9,依赖 fastapipydantic>=2typing_extensions>=4.8,详见 pyproject.toml):

pip install scalar-fastapi

仓库中 playground 环境清单 锁定了一套经过验证的版本组合,例如 fastapi==0.135.3pydantic==2.13.0scalar-fastapi==1.8.2uvicorn==0.44.0,可以作为本地验证的参考基线。

二、快速开始:一行代码挂载 /scalar

FastAPI 自带 OpenAPI 支持(默认输出到 /openapi.json),Scalar 正是利用这一点把文档页面“零成本”挂进来。最快的方式是一行调用——add_scalar_reference 会替你注册路由,并自动从应用实例读取标题和 OpenAPI URL:

from fastapi import FastAPI
from scalar_fastapi import add_scalar_reference

app = FastAPI()

add_scalar_reference(app)

随后在浏览器打开 /scalar 即可看到文档页。

你可以更换路由,并把 get_scalar_api_reference 接受的任意参数透传进去:

from scalar_fastapi import add_scalar_reference, Theme

add_scalar_reference(app, route="/docs/scalar", theme=Theme.KEPLER)

add_scalar_reference 自身只接受 route(默认 /scalar)和 include_in_schema(默认 False)两个专属参数,其余关键字参数全部转发给 get_scalar_api_reference

源码视角:add_scalar_reference 到底做了什么

实现代码 只有短短十几行,值得完整理解:

def add_scalar_reference(
    app: FastAPI,
    *,
    route: str = "/scalar",
    include_in_schema: bool = False,
    **kwargs: Any,
) -> FastAPI:
    # Fall back to the app's own values, but let callers override either one.
    kwargs.setdefault("openapi_url", app.openapi_url)
    kwargs.setdefault("title", app.title)

    @app.get(route, include_in_schema=include_in_schema)
    async def scalar_html() -> HTMLResponse:
        return get_scalar_api_reference(**kwargs)

    return app

从源码结构看,有四个关键设计点:

  • 自动填充:通过 kwargs.setdefaultapp.openapi_url(FastAPI 默认即 /openapi.json)和 app.title 兜底取值;调用方显式传入的 titleopenapi_url 优先于应用默认值。
  • 不污染 OpenAPI 文档include_in_schema 默认为 False/scalar 路由不会出现在 /openapi.jsonpaths 里。这一点由 测试 test_route_is_hidden_from_schema_by_default 验证。
  • 可链式调用:函数返回 app 本身,测试 test_returns_the_app_for_chaining 断言 add_scalar_reference(app) is app
  • 自定义路由即唯一路由:传 route="/docs/scalar" 时默认 /scalar 不再注册(测试 test_custom_route_and_passthrough_kwargs 断言此时访问 /scalar 返回 404),且透传的 theme=Theme.KEPLERtitle="Docs" 均生效。

仓库 playground 就是官方示例:add_scalar_reference(app, theme=Theme.KEPLER) 加上两个业务路由,按 playground 说明 执行 pip install -r requirements.txt 后运行 uvicorn main:app --reload,访问 http://127.0.0.1:8000/scalar 即可体验。

三、自定义路由:完全掌控 get_scalar_api_reference

如果你需要完全控制路由行为(例如挂到自定义前缀、加权限依赖),直接用 get_scalar_api_reference 自己声明路由:

from fastapi import FastAPI
from scalar_fastapi import get_scalar_api_reference

app = FastAPI()

@app.get("/scalar", include_in_schema=False)
async def scalar_html():
    return get_scalar_api_reference(
        # Your OpenAPI document
        openapi_url=app.openapi_url,
        # Avoid CORS issues (optional)
        scalar_proxy_url="https://proxy.scalar.com",
    )

get_scalar_api_reference 返回的是一个 HTMLResponse,其 HTML 骨架为:<head> 中放 <title>、favicon、默认主题 CSS(仅默认主题时注入),<body> 中一个 <div id="app"> 挂载点,然后加载 scalar_js_url 指向的脚本并执行 Scalar.createApiReference("#app", {config_json})。这个“服务端生成静态 HTML + 浏览器端拉取 JS 渲染”的模式,意味着插件本身不打包任何前端资源,文档页面的实际渲染由 CDN 上的 @scalar/api-reference 完成。

四、多 OpenAPI 源(sources)

一个 Scalar 实例可以同时展示多份 OpenAPI 文档,每个源通过 OpenAPISource(Pydantic 模型,extra="forbid" 严格拒绝未知字段)配置:

from scalar_fastapi import get_scalar_api_reference, OpenAPISource

@app.get("/scalar", include_in_schema=False)
async def scalar_html():
    return get_scalar_api_reference(
        sources=[
            OpenAPISource(
                title="User API",
                url="/openapi.json",
                default=True
            ),
            OpenAPISource(
                title="Admin API",
                url="/admin/openapi.json"
            ),
            OpenAPISource(
                title="External API",
                content='{"openapi": "3.0.0", ...}'
            )
        ],
        title="My API Documentation"
    )

源码中 sources 会被 model_dump(exclude_none=True) 转为字典列表后写入配置的 sources 键(见 配置构建逻辑),None 字段自动剔除。

直接传入 OpenAPI 内容(content)

除了 url 指向文档地址,也可以把 OpenAPI 文档直接作为字符串(JSON 或 YAML)或字典传入:

@app.get("/scalar", include_in_schema=False)
async def scalar_html():
    return get_scalar_api_reference(
        content='{"openapi": "3.0.0", "info": {"title": "My API"}}',
        title="My API"
    )

三者存在明确的优先级:sources > content > openapi_url;若三者均未提供,则回退到标准 FastAPI 地址 /openapi.json(见 优先级分支)。

五、Agent:在 API 文档中内置 AI 聊天

Agent 为 API 文档添加 AI 聊天界面。默认在 localhost 上可用(免费消息有限);生产环境需要使用 Agent key(获取方式见 Agent key 指南),完整说明见 Agent 配置章节

按源启用 Agent(带 key)

from scalar_fastapi import get_scalar_api_reference, OpenAPISource, AgentScalarConfig

@app.get("/scalar", include_in_schema=False)
async def scalar_html():
    return get_scalar_api_reference(
        sources=[
            OpenAPISource(
                title="User API",
                url="/openapi.json",
                default=True,
                agent=AgentScalarConfig(key="your-agent-scalar-key"),
            ),
        ],
        title="My API Documentation"
    )

整体禁用 Agent

from scalar_fastapi import get_scalar_api_reference, AgentScalarConfig

@app.get("/scalar", include_in_schema=False)
async def scalar_html():
    return get_scalar_api_reference(
        openapi_url="/openapi.json",
        agent=AgentScalarConfig(disabled=True),
    )

AgentScalarConfig 是严格模式 Pydantic 模型,只有两个字段:key(生产环境必填,localhost 之外使用 Agent 需要 key)与 disabled(置 True 表示完全关闭),多余字段会直接报错。两个方向的序列化均被测试覆盖:顶层 agent 输出 "agent": {"disabled": true},按源 agent 输出在 sources 内部(见 相关测试)。

六、完整配置参数参考

get_scalar_api_reference 支持的全部参数如下(默认值与 函数签名 一致),当前可用的更多配置语义见 官方配置总览

核心配置

参数 默认值 说明
openapi_url None Scalar 要加载的 OpenAPI URL。若提供了 contentsources,此参数被忽略
content None 直接传入 OpenAPI/Swagger 文档,字符串(JSON 或 YAML)或字典。若提供了 sources,此参数被忽略
sources None 多份 OpenAPI 文档列表,每个源可含 titleslugurlcontentdefault 等字段
title "Scalar" 页面 <title>(浏览器标签页标题)
scalar_js_url "https://cdn.jsdelivr.net/npm/@scalar/api-reference" 加载 Scalar JavaScript 的地址,通常指向 CDN,可换成自建/私有源
scalar_favicon_url "https://fastapi.tiangolo.com/img/favicon.png" 页面 favicon 地址(此默认值见 源码签名

OpenAPISource 字段

使用多源时,每个 OpenAPISource 可配置:

  • title(默认 None)- API 的显示名称。未提供时回退为 API #1API #2 等;
  • slug(默认 None)- API 的 URL 标识。未提供时由 title 或索引自动生成;
  • url(默认 None)- OpenAPI 文档地址(JSON 或 YAML),与 content 互斥;
  • content(默认 None)- 直接文档内容(JSON/YAML 字符串或字典),与 url 互斥;
  • default(默认 False)- 多源时该源是否为默认源;
  • agent(默认 None)- 该源的 Agent 配置(keydisabled),详见 Agent 配置

显示选项

  • layout(默认 Layout.MODERN
  • show_sidebar(默认 True
  • hide_models(默认 False
  • hide_search(默认 False)- 是否显示侧边栏搜索框
  • hide_test_request_button(默认 False)- 是否显示 “Test Request” 按钮
  • hide_download_button(默认 False)- 已弃用:请改用 document_download_type;源码中它仍被支持,但仅在为 True 时写入 hideDownloadButton
  • document_download_type(默认 DocumentDownloadType.BOTH)- 文档下载按钮提供的文件类型,选项:JSONYAMLBOTHNONE
  • show_developer_tools(默认 "localhost")- 顶部开发者工具面板何时显示,选项:"always""localhost""never"
  • plugin_urls(默认 None/空)- 提供附加 API Reference 插件的 ESM 模块 URL 列表,每个模块在 API Reference 挂载前被浏览器导入(该参数见 源码 Doc

DocumentDownloadType 枚举

from scalar_fastapi import DocumentDownloadType

# 可用选项:
DocumentDownloadType.JSON    # 仅下载 JSON
DocumentDownloadType.YAML    # 仅下载 YAML
DocumentDownloadType.BOTH    # JSON 和 YAML 都提供(默认)
DocumentDownloadType.NONE    # 隐藏下载按钮

主题与外观

  • dark_mode(默认 None)- 初始是否开启暗色模式;留空则跟随读者偏好
  • force_dark_mode_state(默认 None)- 强制暗色模式始终处于该状态,取值 'dark''light'
  • hide_dark_mode_toggle(默认 False)- 是否隐藏暗色模式切换按钮
  • with_default_fonts(默认 True)- 是否使用默认字体(Inter 与 JetBrains Mono)
  • custom_css(默认 "")- 应用到 API 文档页的自定义 CSS 字符串
  • theme(默认 Theme.DEFAULT)- 主题选择,见下文 Theme 枚举

搜索与导航

  • search_hot_key(默认 SearchHotKey.K
  • default_open_all_tags(默认 False
  • expand_all_model_sections(默认 False)- 是否默认展开所有模型章节
  • expand_all_responses(默认 False)- 是否默认展开所有响应章节
  • order_required_properties_first(默认 True)- schema 对象中是否将必填属性排在前面
  • order_schema_properties_by(默认 "alpha")- schema 属性排序,选项:"alpha"(字母序)、"preserve"(保持原文档顺序)

服务器配置

  • base_server_url(默认 "")- 给所有相对 server 地址加前缀的基础 URL
  • servers(默认 None/空)- OpenAPI Server Object 列表,每项必须含 url(string),可选 description(string)与 variables(map)。示例:[{"url": "https://api.example.com", "description": "Production"}]
  • hidden_clients(默认无)- 隐藏指定客户端。接受字符串列表,或“目标名 → 布尔值/客户端名列表”的字典(布尔值表示隐藏该目标下全部客户端),兼容旧版列表写法

认证

  • authentication(默认 None/空)- 附加认证信息字典,按认证 scheme 名映射到凭证结构
  • hide_client_button(默认 False)- 是否隐藏侧边栏与弹窗中的客户端按钮
  • persist_auth(默认 False)- 是否把认证凭证持久化到 local storage

高级选项

  • scalar_js_url(默认 "https://cdn.jsdelivr.net/npm/@scalar/api-reference"
  • scalar_proxy_url(默认 "")- 代理地址,用于规避跨域问题
  • integration(默认 "fastapi")- 集成标记,写入配置的 _integration 键;设为 None 则完全省略
  • theme(默认 Theme.DEFAULT
  • agent(默认 None)- 设为 AgentScalarConfig(disabled=True) 可整体关闭 Agent;按源配 key 请使用 OpenAPISourceagent 字段。详见 Agent
  • overrides(默认 None/空)- 直接合并进最终 config 字典的覆盖项,该字典即 Scalar.createApiReference("#app", ...) 的第二个参数
  • telemetry(默认 True)- 开关 API 客户端使用遥测(仅记录是否有请求经 API client 发出)

Layout 枚举

from scalar_fastapi import Layout

# 可用选项:
Layout.MODERN    # 现代布局(默认)
Layout.CLASSIC   # 经典布局

SearchHotKey 枚举

SearchHotKey 每个字母对应一个成员,SearchHotKey.ASearchHotKey.Z。所选键会与平台修饰键组合使用(macOS 为 Cmd,其他平台为 Ctrl)。默认是 SearchHotKey.K

from scalar_fastapi import SearchHotKey

get_scalar_api_reference(
    openapi_url="/openapi.json",
    search_hot_key=SearchHotKey.S,  # Cmd/Ctrl + S
)

Theme 枚举

from scalar_fastapi import Theme

# 可用选项(默认 Theme.DEFAULT):
Theme.DEFAULT
Theme.ALTERNATE
Theme.MOON
Theme.PURPLE
Theme.SOLARIZED
Theme.BLUE_PLANET
Theme.SATURN
Theme.KEPLER
Theme.MARS
Theme.DEEP_SPACE
Theme.LASERWAVE
Theme.NONE  # 不使用任何 Scalar 主题渲染

主题枚举共 12 个成员且取值互不相同(bluePlanetdeepSpace 等为驼峰字符串),这一点由 测试 逐一断言。

七、源码实现原理:配置如何变成页面

只序列化“非默认值”

配置构建段 的策略是:从空 config 字典开始,逐项判断——只有当参数偏离默认值时才写入对应的驼峰键(如 proxyUrllayoutshowSidebarsearchHotKey 等),最后把 overrides 整体 config.update(overrides)。好处是生成的内联 JSON 尽量精简;test_default_parameters 测试专门验证了默认配置下 proxyUrllayoutthemeagent 等键均不出现在 Scalar.createApiReference 的配置段中。

枚举与纯字符串等价

函数入口先做统一归一化:

layout = layout.value if isinstance(layout, Enum) else layout
theme = theme.value if isinstance(theme, Enum) else theme
search_hot_key = search_hot_key.value if isinstance(search_hot_key, Enum) else search_hot_key
document_download_type = (
    document_download_type.value
    if isinstance(document_download_type, Enum)
    else document_download_type
)

因此 theme="moon"theme=Theme.MOON 生成的 HTML 完全一致——test_string_and_enum_produce_identical_output 直接对两种调用产出的 HTML 做了逐字节相等断言;而默认值字符串("modern""default""k")同样会被省略。

默认主题的 CSS 注入

当且仅当 theme == "default" 时,模板会把一段内置的 scalar_theme CSS(定义 .light-mode/.dark-mode--scalar-color-*--scalar-background-*--scalar-sidebar-* 等约 200 行 CSS 变量)注入 <style> 标签;选择其他主题或 Theme.NONE 时这段内联样式不出现,页面改由 CDN 脚本按 theme 键处理。test_default_theme_string_still_injects_styles 用 CSS 变量 --scalar-color-accent 是否存在来验证这一行为。

安全细节:标题转义与脚本逃逸防护

生成 HTML 前有专门的两层防护(见 源码注释与实现):

page_title = escape_html(title) if title else "Scalar"
config_json = json.dumps(config).replace("</", "<\\/")
  • title 经过 html.escape,含 <script> 的标题会被转义为 &lt;script&gt;,不会注入标记;
  • 序列化后的配置 JSON 中所有 </ 替换为 <\/,防止 content 里夹带的 </script> 提前终止内联 <script> 块。

对应测试 test_special_characters_in_title_are_escapedtest_content_with_closing_script_tag_cannot_break_out 分别用 <script>alert('xss')</script> 标题和 "</script><script>alert(1)</script>" 文档内容验证了这两道防线(JSON 中 <\/ 是合法转义,浏览器解析后仍还原为 </,不影响 OpenAPI 内容本身)。

测试与运行验证

  • 单元测试 覆盖了:HTML 结构(<!doctype html><div id="app">Scalar.createApiReference("#app")、全部主题的序列化、servers/authentication/hidden_clients 复杂结构、integration=None_integration 不出现、show_developer_tools="never"、FastAPI TestClient 端到端请求 /scalar 返回 text/html 等;
  • 另有 集成测试导入测试 保证 __all__ 导出面(add_scalar_referenceget_scalar_api_referenceLayoutOpenAPISourceAgentScalarConfigSearchHotKeyThemeDocumentDownloadType,见 包导出)稳定;
  • 版本同步机制:pyproject.toml 中 Hatchling 的 <a href="https://link.gitcode.com/i/470f8c680b15bdbebb21e8bb29c3ed0c" target="_blank">tool.hatch.version] 直接从 [package.json 的 version 字段取版本号,保证 Python 包与 monorepo 版本一致。

八、小结

scalar-fastapi 的设计非常克制:服务端只负责“按 Pythonic 参数生成一段携带精简配置的静态 HTML”,真正的工作交给 CDN 上的 @scalar/api-reference 前端。对使用者的核心心智模型是三件事——

  1. 接入口add_scalar_reference(app) 一行接入,或 get_scalar_api_reference 自定义路由;
  2. 数据源优先级sources > content > openapi_url > 兜底 /openapi.json
  3. 一切参数皆默认值省略:只写偏离默认值的配置项,另可用 overrides 做最终兜底覆盖,agenttelemetryshow_developer_tools 提供了行为开关,scalar_js_urlscalar_proxy_url 支持私有化部署与代理。

结合上文配置表与源码路径,你可以在 FastAPI 项目中完整落地并验证这套方案:所有关键行为都能在 integrations/fastapi 目录下找到对应的实现与测试依据。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
34
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.21 K
2.81 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
945
1.86 K
docsdocs
暂无描述
Markdown
906
5.84 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
537
607
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
864
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
4.28 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.39 K
1.48 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
550
401
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.19 K
347