fastapi: docs中执行到接口的访问时,配置请求前缀
一,配置:
下面的配置针对的是:父子应用,当前子应用前缀/api, 而且重写了docs的显示:
# 创建FastAPI应用,并传入 lifespan
api_app = FastAPI(title="我的API项目",
# docs_url=None,
docs_url=None,
redoc_url=None,
openapi_url=None,
root_path="/api",
)
if IS_DEV:
security = HTTPBasic(realm="ApiPortal")
# 2. 账号密码校验函数
def datetime_verify_docs(credentials: HTTPBasicCredentials = Depends(security)):
# 使用 secrets.compare_digest 防范计时攻击 (Timing Attacks)
correct_username = secrets.compare_digest(credentials.username, "api_user")
correct_password = secrets.compare_digest(credentials.password, "123456")
if not (correct_username and correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="用户名或密码错误",
headers={"WWW-Authenticate": 'Basic realm="ApiPortal"'},
)
return credentials.username
# 3. 手动重写 /openapi.json 并加锁
@api_app.get("/openapi.json", include_in_schema=False)
async def get_open_api_endpoint(request: Request,username: str = Depends(datetime_verify_docs)):
if IS_DEV:
# 动态获取当前的 root_path (即 "/api")
root_path = request.scope.get("root_path", "")
# 显式构造 servers 参数
servers = [{"url": root_path}] if root_path else [{"url": "/"}]
# 手动触发 get_openapi,并把包含前缀的 servers 传进去
openapi_schema = get_openapi(
title=api_app.title,
version=api_app.version,
routes=api_app.routes,
servers=servers # <-- 关键:告诉 Swagger UI 调试时必须加这个前缀!
)
return openapi_schema
else:
return None
# 4. 手动重写 /docs 并加锁
@api_app.get("/docs", include_in_schema=False)
async def get_documentation(request: Request, username: str = Depends(datetime_verify_docs)):
root_path = request.scope.get("root_path", "").rstrip("/")
return get_swagger_ui_html(openapi_url=f"{root_path}/openapi.json",
title=api_app.title + " - Docs",
# 【核心修正 3】:静态资源路径也必须拼接 root_path,否则会去根目录下找,导致404或找错
swagger_js_url=f"/static/swagger/swagger-ui-bundle.js",
swagger_css_url=f"/static/swagger/swagger-ui.css",
swagger_favicon_url=f"/static/swagger/favicon.png"
)
二,测试效果:
未添加前缀前:

添加前缀后:

浙公网安备 33010602011771号