FastAPi上手快且底层嵌套了Swagger会自动生成接口文档,开开心心的写好应用程序部署,结果访问127.0.0.1:8000/docs接口文档的网址访问不了
cdn的地址访问不了,但是有时又能进入,估计是访问Swagger网站的人多了,导致有时候获取资源地址失败,并且如果服务部署在内网无法访问外部的地址的时候也是无法访问127.0.0.1:8000/docs网址的,原因也是swagger的css和js的静态资源无法获取。
下面介绍三种一劳永逸的方式方式不访问Swagger资源地址改为访问本地静态文件
首先在网站能访问的时候下载静态资源到本地保持到一个static的文件中
无法下载的可以在一下链接下载
fastapi==0.95.0版本的swagger静态文件
链接:百度网盘 请输入提取码 提取码:32fc
1、 修改fastapi的源码
将static文件放在项目的根路径中
修改FastApi源码中调用cdn地址的位置,代码位置在fastapi/openapi/docs.py中,将访问cdn的网站代码替换成访问本地静态文件地址
挂载静态文件
app = FastAPI()
# 挂载静态文件
app.mount("/static", StaticFiles(directory="static"), name="static")
官方文档对挂载的解释
在访问将从本地静态文件中读取,能成功访问接口文档
2、 修改默认参数方法
显然上一个方法不及备python的风格,别人运行你的项目时还要求别人修改FastApi的源码不现实,而且如果在线上进行Docker部署还需要修改FastApi源码也挺麻烦的,下面介绍项目不用修改FastApi中源码中的方法来实现。
python中一切皆对象,函数也是一个function对象,函数中的形参和默认参数都有保存在函数对象中,而默认参数的值就保存在__kwdefaults__中,只要在项目启动时候修改fastapi/openapi/docs.py 中函数get_swagger_ui_html的默认值就能实现不用修改源码了。
和一种方式一样将static文件放在项目根路径中
修改项目的代码
app = FastAPI()
# 1.挂载static文件夹
app.mount("/static", StaticFiles(directory="static"), name="static")
# 2.修改get_swagger_ui_html函数的默认参数
sys.modules["fastapi.openapi.docs"].\
get_swagger_ui_html.__kwdefaults__["swagger_js_url"] = "/static/swagger-ui-bundle.js"
sys.modules["fastapi.openapi.docs"].\
get_swagger_ui_html.__kwdefaults__["swagger_css_url"] = "/static/swagger-ui.css"
上面的修改之后同样也能够访问到接口文档
3、重写docs接口
第二钟方式虽然也能做到不修改FastApi源代码的情况下访问接口文档,但是也不是很优雅,动态修改函数的默认值也不是python推荐的方式。能不能做到通过重写/docs接口而修改swagger静态文件的地址呢。
答案时可以的
同样先将static文件放在项目的根路径下
项目代码中重写docs接口
# 1.不用系统定义的
app = FastAPI(docs_url=None)
# 2.挂载目录
app.mount("/static", StaticFiles(directory="static"), name="static")
# 3.重写docs接口
@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",
)
也能正常访问本地static下的文件
总结
推荐使用第三种方式
完整的测试代码
# 05.py
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
import uvicorn
from fastapi.openapi.docs import (
get_swagger_ui_html,
)
app = FastAPI(docs_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("/home", tags=["这是home测试接口"],
summary="这是一个测试接口的总结,测试home接口",
description="这是测试接口的详情描述",
response_description="这是响应的详情描述",
deprecated=False)
def home():
return {"user_id": 1001}
if __name__ == '__main__':
uvicorn.run("05:app", reload=True)