diff --git a/src/blueapi/service/main.py b/src/blueapi/service/main.py index ba5d022d2..9711f2005 100644 --- a/src/blueapi/service/main.py +++ b/src/blueapi/service/main.py @@ -71,6 +71,7 @@ VENDOR_CONTEXT_HEADER = "tracestate" AUTHORIZAITON_HEADER = "authorization" PROPAGATED_HEADERS = {CONTEXT_HEADER, VENDOR_CONTEXT_HEADER, AUTHORIZAITON_HEADER} +DOCS_ENDPOINT = "/docs" class Tag(str, Enum): @@ -132,7 +133,7 @@ async def inner(app: FastAPI): def get_app(config: ApplicationConfig): app = FastAPI( - docs_url="/docs", + docs_url=DOCS_ENDPOINT, title="BlueAPI Control", summary="BlueAPI wraps bluesky plans and devices and " "exposes endpoints to send commands/receive data", @@ -205,6 +206,14 @@ async def on_token_error_401(_: Request, __: Exception): ) +@secure_router.get("/", include_in_schema=False) +def root_redirect() -> RedirectResponse: + """Redirect to docs url""" + return RedirectResponse( + status_code=status.HTTP_307_TEMPORARY_REDIRECT, url=DOCS_ENDPOINT + ) + + @secure_router.get("/environment", tags=[Tag.ENV]) @start_as_current_span(TRACER, "runner") def get_environment( diff --git a/tests/unit_tests/service/test_rest_api.py b/tests/unit_tests/service/test_rest_api.py index 0c731723f..b0bc09dd3 100644 --- a/tests/unit_tests/service/test_rest_api.py +++ b/tests/unit_tests/service/test_rest_api.py @@ -744,6 +744,16 @@ def test_logout( ) +def test_docs_redirect( + mock_authn_server, + client_with_auth: TestClient, +): + client_with_auth.follow_redirects = False + response = client_with_auth.get("/") + assert response.headers.get("location") == main.DOCS_ENDPOINT + assert response.status_code == status.HTTP_307_TEMPORARY_REDIRECT + + @pytest.mark.parametrize("has_oidc_config", [True, False]) def test_logout_when_oidc_config_invalid( has_oidc_config: bool,