自定义文档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@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文档获取**JavaScript**文件的URL。这是自定义CDN的URL。swagger_css_url
:你的Swagger UI文档获取**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}"}
Tip
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在某些情况下可能很有用,例如,你需要你的应用在离线时、没有开放互联网访问或局域网中继续工作。
在这里,你将看到如何自己在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生成的API参考文档
* -------------------------------------------------------------
* 版本: "2.0.0-rc.18"
* 仓库: 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。这是你的应用现在正在提供的文件。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}"}
Tip
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的文档并与其交互。