自定义文档 UI 静态资源(自托管)¶
API 文档使用 Swagger UI 和 ReDoc,它们都需要一些 JavaScript 和 CSS 文件。
默认情况下,这些文件是通过 CDN 提供的。
但你可以自定义此配置,设置特定的 CDN,或者由你自己托管这些文件。
JavaScript 和 CSS 的自定义 CDN¶
假设你想使用不同的 CDN,例如你想使用 https://unpkg.com/。
如果你所在的国家/地区限制了某些 URL,这可能会很有用。
禁用自动文档¶
第一步是禁用自动文档,因为默认情况下它们使用默认的 CDN。
要禁用它们,请在创建 FastAPI 应用时将其 URL 设置为 None
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
app = FastAPI(docs_url=None, redoc_url=None)
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="https://unpkg.com/redoc@2/bundles/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
包含自定义文档¶
现在你可以为自定义文档创建路径操作了。
你可以复用 FastAPI 的内部函数来创建文档的 HTML 页面,并将所需的参数传递给它们
openapi_url:文档的 HTML 页面可以获取 API 的 OpenAPI 架构的 URL。此处可以使用app.openapi_url属性。title:API 的标题。oauth2_redirect_url:此处可以使用app.swagger_ui_oauth2_redirect_url以使用默认值。swagger_js_url:Swagger UI 文档的 HTML 获取 JavaScript 文件的 URL。这是自定义 CDN URL。swagger_css_url:Swagger UI 文档的 HTML 获取 CSS 文件的 URL。这是自定义 CDN URL。
ReDoc 的处理方式类似...
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
app = FastAPI(docs_url=None, redoc_url=None)
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="https://unpkg.com/redoc@2/bundles/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
提示
swagger_ui_redirect 的路径操作是使用 OAuth2 时的辅助功能。
如果你将 API 与 OAuth2 提供程序集成,你将能够进行身份验证,并使用获得的凭据返回 API 文档,然后使用真实的 OAuth2 身份验证与 API 交互。
Swagger UI 会在后台为你处理这些,但它需要这个“重定向”辅助工具。
创建路径操作进行测试¶
现在,为了测试一切是否正常,请创建一个路径操作
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
app = FastAPI(docs_url=None, redoc_url=None)
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="https://unpkg.com/redoc@2/bundles/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
进行测试¶
现在,你应该能够访问 http://127.0.0.1:8000/docs 查看文档,刷新页面后,它将从新的 CDN 加载这些资源。
文档的 JavaScript 和 CSS 自托管¶
如果你的应用需要在离线、没有开放互联网连接或在局域网中保持工作,那么自托管 JavaScript 和 CSS 可能很有用。
这里你将看到如何在同一个 FastAPI 应用中自行托管这些文件,并配置文档以使用它们。
项目文件结构¶
假设你的项目文件结构如下所示
.
├── app
│ ├── __init__.py
│ ├── main.py
现在创建一个目录来存储这些静态文件。
你的新文件结构可能如下所示
.
├── app
│ ├── __init__.py
│ ├── main.py
└── static/
下载文件¶
下载文档所需的静态文件,并将它们放在 static/ 目录中。
你可以右键点击每个链接,选择类似于“链接另存为...”的选项。
Swagger UI 使用以下文件:
而 ReDoc 使用文件:
此后,你的文件结构可能如下所示
.
├── app
│ ├── __init__.py
│ ├── main.py
└── static
├── redoc.standalone.js
├── swagger-ui-bundle.js
└── swagger-ui.css
托管静态文件¶
- 导入
StaticFiles。 - 在特定路径“挂载”(Mount)
StaticFiles()实例。
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
测试静态文件¶
启动你的应用程序并访问 http://127.0.0.1:8000/static/redoc.standalone.js。
你应该会看到一个非常长的 ReDoc JavaScript 文件。
它可能以如下内容开头
/*! For license information please see redoc.standalone.js.LICENSE.txt */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
...
这确认了你能够从你的应用中托管静态文件,并且你已将文档的静态文件放置在正确的位置。
现在我们可以配置应用以使用这些静态文件来生成文档。
禁用静态文件的自动文档¶
与使用自定义 CDN 时相同,第一步是禁用自动文档,因为它们默认使用 CDN。
要禁用它们,请在创建 FastAPI 应用时将其 URL 设置为 None
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
包含静态文件的自定义文档¶
同样,你可以为自定义文档创建路径操作。
再次强调,你可以复用 FastAPI 的内部函数来创建 HTML 页面,并将所需参数传递给它们
openapi_url:文档的 HTML 页面可以获取 API 的 OpenAPI 架构的 URL。此处可以使用app.openapi_url属性。title:API 的标题。oauth2_redirect_url:此处可以使用app.swagger_ui_oauth2_redirect_url以使用默认值。swagger_js_url:Swagger UI 文档的 HTML 获取 JavaScript 文件的 URL。这是你的应用现在正在托管的文件。swagger_css_url:Swagger UI 文档的 HTML 获取 CSS 文件的 URL。这是你的应用现在正在托管的文件。
ReDoc 的处理方式类似...
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
提示
swagger_ui_redirect 的路径操作是使用 OAuth2 时的辅助功能。
如果你将 API 与 OAuth2 提供程序集成,你将能够进行身份验证,并使用获得的凭据返回 API 文档,然后使用真实的 OAuth2 身份验证与 API 交互。
Swagger UI 会在后台为你处理这些,但它需要这个“重定向”辅助工具。
创建路径操作以测试静态文件¶
现在,为了测试一切是否正常,请创建一个路径操作
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
测试静态文件 UI¶
现在,你应该可以断开 WiFi,访问 http://127.0.0.1:8000/docs 并刷新页面。
即使没有互联网,你也能看到 API 的文档并与之交互。