自定义文档 UI 静态资源 (自托管)¶
API 文档使用 Swagger UI 和 ReDoc,它们都需要一些 JavaScript 和 CSS 文件。
默认情况下,这些文件从 CDN 提供。
但您可以自定义它,可以设置特定的 CDN,或者自己提供文件。
自定义 CDN 用于 JavaScript 和 CSS¶
假设您想使用不同的 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@next/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@next/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 身份验证与它进行交互。
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@next/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 在以下情况下可能有用:例如,您需要您的应用程序即使在脱机状态下或在本地网络中,在没有打开 Internet 访问的情况下也能正常工作。
在这里,您将了解如何在同一个 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
。 - 在特定路径中“挂载”一个
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 文件。
它可能以类似于以下内容开头
/*!
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
* -------------------------------------------------------------
* Version: "2.0.0-rc.18"
* Repo: https://github.com/Redocly/redoc
*/
!function(e,t){"object"==typeof exports&&"object"==typeof m
...
这确认您能够从应用程序提供静态文件,并且将文档的静态文件放置在正确的位置。
现在我们可以配置应用程序以使用这些静态文件来生成文档。
禁用静态文件的自动文档¶
与使用自定义 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}"}
包含静态文件的自定义文档¶
与自定义 CDN 相同,现在您可以为自定义文档创建路径操作。
同样,您可以重复使用 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。这是您的应用程序现在正在提供的 URL。swagger_css_url
: Swagger UI 文档的 HTML 获取 CSS 文件的 URL。这是您的应用程序现在正在提供的 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 身份验证与它进行交互。
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 的文档并与之交互。