Add test for self-hosted docs behind a proxy
Related to #10978, #11033, #11160 and #11622
No code changes here, but adds a test for static assets when using root_path (behind a proxy)
Note, this test passes in <=0.108.0 and fails beginning at 0.109.0.
response = client.get("/openapi.json")
response = client.get("/static/swagger.js")
response = client.get("/static/swagger.css")
assert "/static/swagger.js" in swagger_html
assert f"{root_path}/static/swagger.js" not in swagger_html
assert "/static/swagger.css" in swagger_html
assert f"{root_path}/static/swagger.css" not in swagger_html
The lines above are actually wrong. Since our app is behind the proxy with prefix '/api', all assets' paths should start with root_path ('/api')
There is an issue (IMO) in Starlette that makes static files inaccessible via path without prefix (those that don't start with root_path).
Read more: https://github.com/encode/starlette/discussions/2931
Although, there is still a minor issue here.
The code of custom_swagger_ui_html should actually include adding root_path prefix to all assets.
So, I think the related code example in docs should be updated.
async def custom_swagger_ui_html(request: Request):
"""
Sets up a localized version of the Swagger (OpenAPI) docs that can be run without assets from the Internet.
"""
root_path = request.scope.get("root_path", "").rstrip("/")
return get_swagger_ui_html(
openapi_url=root_path + "/openapi.json",
title=app.title,
swagger_js_url=root_path + "/static/swagger.js",
swagger_css_url=root_path + "/static/swagger.css",
)
In tests, all paths should be updated to start with root_path prefix:
response = client.get(f"{root_path}/openapi.json")
assert response.status_code == 200
response = client.get(f"{root_path}/static/swagger.js")
assert response.status_code == 200
response = client.get(f"{root_path}/static/swagger.css")
assert response.status_code == 200
assert f"{root_path}/static/swagger.js" in swagger_html
assert f"{root_path}/static/swagger.css" in swagger_html
@bertomaniac, would you like to work on this?
@YuriiMotov Sure. I could probably look at starting on this in the next couple of weeks.
Just to be clear: You're talking about updating these tests and then updating the documentation as well?
IMO, ideally we just need to update docs example (add root_path prefixes to URLs of assets as it's done in the original endpoint function) and parameterize test for that code example from docs to use app with and without root_path (using client = TestClient(app=app, root_path=..)?).
Hope I was clear enough 🙂
Actually, I would close this PR and start new one from scratch to keep it clean and easy to review.
But don't trust me blindly, double-check please
@YuriiMotov
I think I got things in order. New PR is here: https://github.com/fastapi/fastapi/pull/13825
Closing this in favor of new #13825