Repository: deepset-ai/haystack

Issue:
Add `draw()` method to trigger pipeline image visualization
**Is your feature request related to a problem? Please describe.**
The pipeline image shows up when the `add_component` and `connect` methods are called. This is sometimes problematic because:
* The image takes up a lot of space
* Sometimes, the image creation raises an error as the mermaid service can be unstable from time to time

**Describe the solution you'd like**
Change the behavior of pipeline images showing up by default and add `show()` method to visualize those images when required

**Describe alternatives you've considered**
Just change the default behavior and not provide a `show()` method (we already have `draw()` method to visualize the image)

**Additional context**
N/A



Discussion:
I think we just need to turn off this auto-show feature: https://github.com/deepset-ai/haystack/blob/main/haystack/core/pipeline/pipeline.py#L91-L94 - not sure I get what the difference would be between draw/show?

Resolving patch:
diff --git a/haystack/core/pipeline/pipeline.py b/haystack/core/pipeline/pipeline.py
--- a/haystack/core/pipeline/pipeline.py
+++ b/haystack/core/pipeline/pipeline.py
@@ -86,13 +86,7 @@ def __eq__(self, other) -> bool:
     def __repr__(self) -> str:
         """
         Returns a text representation of the Pipeline.
-        If this runs in a Jupyter notebook, it will instead display the Pipeline image.
         """
-        if is_in_jupyter():
-            # If we're in a Jupyter notebook we want to display the image instead of the text repr.
-            self.show()
-            return ""
-
         res = f"{object.__repr__(self)}\n"
         if self.metadata:
             res += "🧱 Metadata\n"


Test patch:
diff --git a/test/core/pipeline/test_pipeline.py b/test/core/pipeline/test_pipeline.py
--- a/test/core/pipeline/test_pipeline.py
+++ b/test/core/pipeline/test_pipeline.py
@@ -281,8 +281,7 @@ def test_get_component_name_not_added_to_pipeline():
     assert pipe.get_component_name(some_component) == ""
 
 
-@patch("haystack.core.pipeline.pipeline.is_in_jupyter")
-def test_repr(mock_is_in_jupyter):
+def test_repr():
     pipe = Pipeline(metadata={"test": "test"}, max_loops_allowed=42)
     pipe.add_component("add_two", AddFixedValue(add=2))
     pipe.add_component("add_default", AddFixedValue())
@@ -302,26 +301,8 @@ def test_repr(mock_is_in_jupyter):
         "  - add_two.result -> double.value (int)\n"
         "  - double.value -> add_default.value (int)\n"
     )
-    # Simulate not being in a notebook
-    mock_is_in_jupyter.return_value = False
-    assert repr(pipe) == expected_repr
-
 
-@patch("haystack.core.pipeline.pipeline.is_in_jupyter")
-def test_repr_in_notebook(mock_is_in_jupyter):
-    pipe = Pipeline(metadata={"test": "test"}, max_loops_allowed=42)
-    pipe.add_component("add_two", AddFixedValue(add=2))
-    pipe.add_component("add_default", AddFixedValue())
-    pipe.add_component("double", Double())
-    pipe.connect("add_two", "double")
-    pipe.connect("double", "add_default")
-
-    # Simulate being in a notebook
-    mock_is_in_jupyter.return_value = True
-
-    with patch.object(Pipeline, "show") as mock_show:
-        assert repr(pipe) == ""
-        mock_show.assert_called_once_with()
+    assert repr(pipe) == expected_repr
 
 
 def test_run_raises_if_max_visits_reached():