diff --git a/langserve/api_handler.py b/langserve/api_handler.py index 4be0776e..0094d3e6 100644 --- a/langserve/api_handler.py +++ b/langserve/api_handler.py @@ -1565,11 +1565,27 @@ async def playground( self._run_name, user_provided_config, request ) + # Fetching the playground URL using information in the route + # to support a case when the APIRouter is nested inside another + # APIRouter. + # In this case the prefix attribute of the APIRouter is not enough + # to get the correct playground URL. + route = request.scope["route"] + suffix = "/{file_path:path}" + route_path = route.path + full_suffix = "/playground" + suffix + + if not route_path.endswith(full_suffix): + raise AssertionError( + f"Expected route to end with " f"'{full_suffix}'. Got: {route.path}" + ) + + # path without the suffix playground_url = ( request.scope.get("root_path", "").rstrip("/") - + self._base_url - + "/playground" + + route_path[: -len(f"{suffix}")] ) + feedback_enabled = tracing_is_enabled() and self._enable_feedback_endpoint public_trace_link_enabled = ( tracing_is_enabled() and self._enable_public_trace_link_endpoint diff --git a/tests/unit_tests/test_api_playground.py b/tests/unit_tests/test_api_playground.py index 347aa63f..9caa8745 100644 --- a/tests/unit_tests/test_api_playground.py +++ b/tests/unit_tests/test_api_playground.py @@ -45,6 +45,10 @@ async def test_serve_playground_with_api_router() -> None: async with AsyncClient(app=app, base_url="http://localhost:9999") as client: response = await client.get("/langserve_runnables/chat/playground/index.html") assert response.status_code == 200 + assert ( + 'src="/langserve_runnables/chat/playground/assets/' + in response.content.decode() + ), "html should contain reference to valid playground assets path" async def test_serve_playground_with_api_router_in_api_router() -> None: @@ -67,6 +71,9 @@ async def test_serve_playground_with_api_router_in_api_router() -> None: async with AsyncClient(app=app, base_url="http://localhost:9999") as client: response = await client.get("/parent/bar/foo/playground/index.html") assert response.status_code == 200 + assert ( + 'src="/parent/bar/foo/playground/assets/' in response.content.decode() + ), "html should contain reference to valid playground assets path" async def test_root_path_on_playground() -> None: