Skip to content

Commit bb0e36f

Browse files
authored
feat: increase Mermaid timeout and make it configurable (#8973)
* increase Mermaid timeout and make it configurable * rm e2e trigger * simplify test
1 parent 9581fea commit bb0e36f

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

haystack/core/pipeline/base.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ def outputs(self, include_components_with_connected_outputs: bool = False) -> Di
657657
}
658658
return outputs
659659

660-
def show(self, server_url: str = "https://mermaid.ink", params: Optional[dict] = None) -> None:
660+
def show(self, server_url: str = "https://mermaid.ink", params: Optional[dict] = None, timeout: int = 30) -> None:
661661
"""
662662
Display an image representing this `Pipeline` in a Jupyter notebook.
663663
@@ -683,19 +683,24 @@ def show(self, server_url: str = "https://mermaid.ink", params: Optional[dict] =
683683
- paper: Paper size for PDFs (e.g., 'a4', 'a3'). Ignored if 'fit' is true.
684684
- landscape: Landscape orientation for PDFs (boolean). Ignored if 'fit' is true.
685685
686+
:param timeout:
687+
Timeout in seconds for the request to the Mermaid server.
688+
686689
:raises PipelineDrawingError:
687690
If the function is called outside of a Jupyter notebook or if there is an issue with rendering.
688691
"""
689692
if is_in_jupyter():
690693
from IPython.display import Image, display # type: ignore
691694

692-
image_data = _to_mermaid_image(self.graph, server_url=server_url, params=params)
695+
image_data = _to_mermaid_image(self.graph, server_url=server_url, params=params, timeout=timeout)
693696
display(Image(image_data))
694697
else:
695698
msg = "This method is only supported in Jupyter notebooks. Use Pipeline.draw() to save an image locally."
696699
raise PipelineDrawingError(msg)
697700

698-
def draw(self, path: Path, server_url: str = "https://mermaid.ink", params: Optional[dict] = None) -> None:
701+
def draw(
702+
self, path: Path, server_url: str = "https://mermaid.ink", params: Optional[dict] = None, timeout: int = 30
703+
) -> None:
699704
"""
700705
Save an image representing this `Pipeline` to the specified file path.
701706
@@ -721,12 +726,15 @@ def draw(self, path: Path, server_url: str = "https://mermaid.ink", params: Opti
721726
- paper: Paper size for PDFs (e.g., 'a4', 'a3'). Ignored if 'fit' is true.
722727
- landscape: Landscape orientation for PDFs (boolean). Ignored if 'fit' is true.
723728
729+
:param timeout:
730+
Timeout in seconds for the request to the Mermaid server.
731+
724732
:raises PipelineDrawingError:
725733
If there is an issue with rendering or saving the image.
726734
"""
727735
# Before drawing we edit a bit the graph, to avoid modifying the original that is
728736
# used for running the pipeline we copy it.
729-
image_data = _to_mermaid_image(self.graph, server_url=server_url, params=params)
737+
image_data = _to_mermaid_image(self.graph, server_url=server_url, params=params, timeout=timeout)
730738
Path(path).write_bytes(image_data)
731739

732740
def walk(self) -> Iterator[Tuple[str, Component]]:

haystack/core/pipeline/draw.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ def _validate_mermaid_params(params: Dict[str, Any]) -> None:
129129

130130

131131
def _to_mermaid_image(
132-
graph: networkx.MultiDiGraph, server_url: str = "https://mermaid.ink", params: Optional[dict] = None
132+
graph: networkx.MultiDiGraph,
133+
server_url: str = "https://mermaid.ink",
134+
params: Optional[dict] = None,
135+
timeout: int = 30,
133136
) -> bytes:
134137
"""
135138
Renders a pipeline using a Mermaid server.
@@ -140,6 +143,8 @@ def _to_mermaid_image(
140143
Base URL of the Mermaid server (default: 'https://mermaid.ink').
141144
:param params:
142145
Dictionary of customization parameters. See `validate_mermaid_params` for valid keys.
146+
:param timeout:
147+
Timeout in seconds for the request to the Mermaid server.
143148
:returns:
144149
The image, SVG, or PDF data returned by the Mermaid server as bytes.
145150
:raises ValueError:
@@ -187,7 +192,7 @@ def _to_mermaid_image(
187192

188193
logger.debug("Rendering graph at {url}", url=url)
189194
try:
190-
resp = requests.get(url, timeout=10)
195+
resp = requests.get(url, timeout=timeout)
191196
if resp.status_code >= 400:
192197
logger.warning(
193198
"Failed to draw the pipeline: {server_url} returned status {status_code}",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
enhancements:
3+
- |
4+
Increased default timeout for Mermaid server to 30 seconds. Mermaid server is used to draw Pipelines.
5+
Exposed the timeout as a parameter for the `Pipeline.show` and `Pipeline.draw` methods. This allows
6+
users to customize the timeout as needed.

test/core/pipeline/test_draw.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ def test_to_mermaid_image_does_not_edit_graph(mock_requests):
3939
assert expected_pipe == pipe.to_dict()
4040

4141

42+
@patch("haystack.core.pipeline.draw.requests")
43+
def test_to_mermaid_image_applies_timeout(mock_requests):
44+
pipe = Pipeline()
45+
pipe.add_component("comp1", Double())
46+
pipe.add_component("comp2", Double())
47+
pipe.connect("comp1", "comp2")
48+
49+
mock_requests.get.return_value = MagicMock(status_code=200)
50+
_to_mermaid_image(pipe.graph, timeout=1)
51+
52+
assert mock_requests.get.call_args[1]["timeout"] == 1
53+
54+
4255
def test_to_mermaid_image_failing_request(tmp_path):
4356
pipe = Pipeline()
4457
pipe.add_component("comp1", Double())

0 commit comments

Comments
 (0)