We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Pipeline drawings in Colab have black background
**Describe the bug**
Since Haystack 2.0-beta8, Pipeline drawings in Colab and other environments (VS Code/Pycharm) randomly
have a black background.

![image](https://github.com/deepset-ai/haystack/assets/44616784/0869599a-14b5-4aed-9e96-a8b09d83658a)

These images are not nice and less readable than the previous ones **with transparent background**:
![image](https://github.com/deepset-ai/haystack/assets/44616784/ec5a2bae-6f8a-49b6-b819-d6834c719bed)


**To Reproduce**
Run the [first 2.0 tutorial](https://haystack.deepset.ai/tutorials/27_first_rag_pipeline)


**System:**
 - Haystack version (commit or version number): 2.0-beta8


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `haystack/core/pipeline/draw.py`
Content:
```
1 # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2 #
3 # SPDX-License-Identifier: Apache-2.0
4 import base64
5 import logging
6 
7 import networkx  # type:ignore
8 import requests
9 
10 from haystack.core.errors import PipelineDrawingError
11 from haystack.core.pipeline.descriptions import find_pipeline_inputs, find_pipeline_outputs
12 from haystack.core.type_utils import _type_name
13 
14 logger = logging.getLogger(__name__)
15 
16 
17 def _prepare_for_drawing(graph: networkx.MultiDiGraph) -> networkx.MultiDiGraph:
18     """
19     Add some extra nodes to show the inputs and outputs of the pipeline.
20     Also adds labels to edges.
21     """
22     # Label the edges
23     for inp, outp, key, data in graph.edges(keys=True, data=True):
24         data[
25             "label"
26         ] = f"{data['from_socket'].name} -> {data['to_socket'].name}{' (opt.)' if not data['mandatory'] else ''}"
27         graph.add_edge(inp, outp, key=key, **data)
28 
29     # Add inputs fake node
30     graph.add_node("input")
31     for node, in_sockets in find_pipeline_inputs(graph).items():
32         for in_socket in in_sockets:
33             if not in_socket.senders and in_socket.is_mandatory:
34                 # If this socket has no sender it could be a socket that receives input
35                 # directly when running the Pipeline. We can't know that for sure, in doubt
36                 # we draw it as receiving input directly.
37                 graph.add_edge("input", node, label=in_socket.name, conn_type=_type_name(in_socket.type))
38 
39     # Add outputs fake node
40     graph.add_node("output")
41     for node, out_sockets in find_pipeline_outputs(graph).items():
42         for out_socket in out_sockets:
43             graph.add_edge(node, "output", label=out_socket.name, conn_type=_type_name(out_socket.type))
44 
45     return graph
46 
47 
48 ARROWTAIL_MANDATORY = "--"
49 ARROWTAIL_OPTIONAL = "-."
50 ARROWHEAD_MANDATORY = "-->"
51 ARROWHEAD_OPTIONAL = ".->"
52 MERMAID_STYLED_TEMPLATE = """
53 %%{{ init: {{'theme': 'neutral' }} }}%%
54 
55 graph TD;
56 
57 {connections}
58 
59 classDef component text-align:center;
60 """
61 
62 
63 def _to_mermaid_image(graph: networkx.MultiDiGraph):
64     """
65     Renders a pipeline using Mermaid (hosted version at 'https://mermaid.ink'). Requires Internet access.
66     """
67     # Copy the graph to avoid modifying the original
68     graph_styled = _to_mermaid_text(graph.copy())
69 
70     graphbytes = graph_styled.encode("ascii")
71     base64_bytes = base64.b64encode(graphbytes)
72     base64_string = base64_bytes.decode("ascii")
73     url = "https://mermaid.ink/img/" + base64_string
74 
75     logging.debug("Rendeding graph at %s", url)
76     try:
77         resp = requests.get(url, timeout=10)
78         if resp.status_code >= 400:
79             logger.warning("Failed to draw the pipeline: https://mermaid.ink/img/ returned status %s", resp.status_code)
80             logger.info("Exact URL requested: %s", url)
81             logger.warning("No pipeline diagram will be saved.")
82             resp.raise_for_status()
83 
84     except Exception as exc:  # pylint: disable=broad-except
85         logger.warning("Failed to draw the pipeline: could not connect to https://mermaid.ink/img/ (%s)", exc)
86         logger.info("Exact URL requested: %s", url)
87         logger.warning("No pipeline diagram will be saved.")
88         raise PipelineDrawingError(
89             "There was an issue with https://mermaid.ink/, see the stacktrace for details."
90         ) from exc
91 
92     return resp.content
93 
94 
95 def _to_mermaid_text(graph: networkx.MultiDiGraph) -> str:
96     """
97     Converts a Networkx graph into Mermaid syntax. The output of this function can be used in the documentation
98     with `mermaid` codeblocks and it will be automatically rendered.
99     """
100     # Copy the graph to avoid modifying the original
101     graph = _prepare_for_drawing(graph.copy())
102     sockets = {
103         comp: "".join(
104             [
105                 f"<li>{name} ({_type_name(socket.type)})</li>"
106                 for name, socket in data.get("input_sockets", {}).items()
107                 if (not socket.is_mandatory and not socket.senders) or socket.is_variadic
108             ]
109         )
110         for comp, data in graph.nodes(data=True)
111     }
112     optional_inputs = {
113         comp: f"<br><br>Optional inputs:<ul style='text-align:left;'>{sockets}</ul>" if sockets else ""
114         for comp, sockets in sockets.items()
115     }
116 
117     states = {
118         comp: f"{comp}[\"<b>{comp}</b><br><small><i>{type(data['instance']).__name__}{optional_inputs[comp]}</i></small>\"]:::component"
119         for comp, data in graph.nodes(data=True)
120         if comp not in ["input", "output"]
121     }
122 
123     connections_list = []
124     for from_comp, to_comp, conn_data in graph.edges(data=True):
125         if from_comp != "input" and to_comp != "output":
126             arrowtail = ARROWTAIL_MANDATORY if conn_data["mandatory"] else ARROWTAIL_OPTIONAL
127             arrowhead = ARROWHEAD_MANDATORY if conn_data["mandatory"] else ARROWHEAD_OPTIONAL
128             label = f'"{conn_data["label"]}<br><small><i>{conn_data["conn_type"]}</i></small>"'
129             conn_string = f"{states[from_comp]} {arrowtail} {label} {arrowhead} {states[to_comp]}"
130             connections_list.append(conn_string)
131 
132     input_connections = [
133         f"i{{*}} -- \"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\" --> {states[to_comp]}"
134         for _, to_comp, conn_data in graph.out_edges("input", data=True)
135     ]
136     output_connections = [
137         f"{states[from_comp]} -- \"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\"--> o{{*}}"
138         for from_comp, _, conn_data in graph.in_edges("output", data=True)
139     ]
140     connections = "\n".join(connections_list + input_connections + output_connections)
141 
142     graph_styled = MERMAID_STYLED_TEMPLATE.format(connections=connections)
143     logger.debug("Mermaid diagram:\n%s", graph_styled)
144 
145     return graph_styled
146
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/haystack/core/pipeline/draw.py b/haystack/core/pipeline/draw.py
--- a/haystack/core/pipeline/draw.py
+++ b/haystack/core/pipeline/draw.py
@@ -70,7 +70,7 @@
     graphbytes = graph_styled.encode("ascii")
     base64_bytes = base64.b64encode(graphbytes)
     base64_string = base64_bytes.decode("ascii")
-    url = "https://mermaid.ink/img/" + base64_string
+    url = f"https://mermaid.ink/img/{base64_string}?type=png"
 
     logging.debug("Rendeding graph at %s", url)
     try:

{"golden_diff": "diff --git a/haystack/core/pipeline/draw.py b/haystack/core/pipeline/draw.py\n--- a/haystack/core/pipeline/draw.py\n+++ b/haystack/core/pipeline/draw.py\n@@ -70,7 +70,7 @@\n     graphbytes = graph_styled.encode(\"ascii\")\n     base64_bytes = base64.b64encode(graphbytes)\n     base64_string = base64_bytes.decode(\"ascii\")\n-    url = \"https://mermaid.ink/img/\" + base64_string\n+    url = f\"https://mermaid.ink/img/{base64_string}?type=png\"\n \n     logging.debug(\"Rendeding graph at %s\", url)\n     try:\n", "issue": "Pipeline drawings in Colab have black background\n**Describe the bug**\r\nSince Haystack 2.0-beta8, Pipeline drawings in Colab and other environments (VS Code/Pycharm) randomly\r\nhave a black background.\r\n\r\n![image](https://github.com/deepset-ai/haystack/assets/44616784/0869599a-14b5-4aed-9e96-a8b09d83658a)\r\n\r\nThese images are not nice and less readable than the previous ones **with transparent background**:\r\n![image](https://github.com/deepset-ai/haystack/assets/44616784/ec5a2bae-6f8a-49b6-b819-d6834c719bed)\r\n\r\n\r\n**To Reproduce**\r\nRun the [first 2.0 tutorial](https://haystack.deepset.ai/tutorials/27_first_rag_pipeline)\r\n\r\n\r\n**System:**\r\n - Haystack version (commit or version number): 2.0-beta8\r\n\n", "before_files": [{"content": "# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>\n#\n# SPDX-License-Identifier: Apache-2.0\nimport base64\nimport logging\n\nimport networkx  # type:ignore\nimport requests\n\nfrom haystack.core.errors import PipelineDrawingError\nfrom haystack.core.pipeline.descriptions import find_pipeline_inputs, find_pipeline_outputs\nfrom haystack.core.type_utils import _type_name\n\nlogger = logging.getLogger(__name__)\n\n\ndef _prepare_for_drawing(graph: networkx.MultiDiGraph) -> networkx.MultiDiGraph:\n    \"\"\"\n    Add some extra nodes to show the inputs and outputs of the pipeline.\n    Also adds labels to edges.\n    \"\"\"\n    # Label the edges\n    for inp, outp, key, data in graph.edges(keys=True, data=True):\n        data[\n            \"label\"\n        ] = f\"{data['from_socket'].name} -> {data['to_socket'].name}{' (opt.)' if not data['mandatory'] else ''}\"\n        graph.add_edge(inp, outp, key=key, **data)\n\n    # Add inputs fake node\n    graph.add_node(\"input\")\n    for node, in_sockets in find_pipeline_inputs(graph).items():\n        for in_socket in in_sockets:\n            if not in_socket.senders and in_socket.is_mandatory:\n                # If this socket has no sender it could be a socket that receives input\n                # directly when running the Pipeline. We can't know that for sure, in doubt\n                # we draw it as receiving input directly.\n                graph.add_edge(\"input\", node, label=in_socket.name, conn_type=_type_name(in_socket.type))\n\n    # Add outputs fake node\n    graph.add_node(\"output\")\n    for node, out_sockets in find_pipeline_outputs(graph).items():\n        for out_socket in out_sockets:\n            graph.add_edge(node, \"output\", label=out_socket.name, conn_type=_type_name(out_socket.type))\n\n    return graph\n\n\nARROWTAIL_MANDATORY = \"--\"\nARROWTAIL_OPTIONAL = \"-.\"\nARROWHEAD_MANDATORY = \"-->\"\nARROWHEAD_OPTIONAL = \".->\"\nMERMAID_STYLED_TEMPLATE = \"\"\"\n%%{{ init: {{'theme': 'neutral' }} }}%%\n\ngraph TD;\n\n{connections}\n\nclassDef component text-align:center;\n\"\"\"\n\n\ndef _to_mermaid_image(graph: networkx.MultiDiGraph):\n    \"\"\"\n    Renders a pipeline using Mermaid (hosted version at 'https://mermaid.ink'). Requires Internet access.\n    \"\"\"\n    # Copy the graph to avoid modifying the original\n    graph_styled = _to_mermaid_text(graph.copy())\n\n    graphbytes = graph_styled.encode(\"ascii\")\n    base64_bytes = base64.b64encode(graphbytes)\n    base64_string = base64_bytes.decode(\"ascii\")\n    url = \"https://mermaid.ink/img/\" + base64_string\n\n    logging.debug(\"Rendeding graph at %s\", url)\n    try:\n        resp = requests.get(url, timeout=10)\n        if resp.status_code >= 400:\n            logger.warning(\"Failed to draw the pipeline: https://mermaid.ink/img/ returned status %s\", resp.status_code)\n            logger.info(\"Exact URL requested: %s\", url)\n            logger.warning(\"No pipeline diagram will be saved.\")\n            resp.raise_for_status()\n\n    except Exception as exc:  # pylint: disable=broad-except\n        logger.warning(\"Failed to draw the pipeline: could not connect to https://mermaid.ink/img/ (%s)\", exc)\n        logger.info(\"Exact URL requested: %s\", url)\n        logger.warning(\"No pipeline diagram will be saved.\")\n        raise PipelineDrawingError(\n            \"There was an issue with https://mermaid.ink/, see the stacktrace for details.\"\n        ) from exc\n\n    return resp.content\n\n\ndef _to_mermaid_text(graph: networkx.MultiDiGraph) -> str:\n    \"\"\"\n    Converts a Networkx graph into Mermaid syntax. The output of this function can be used in the documentation\n    with `mermaid` codeblocks and it will be automatically rendered.\n    \"\"\"\n    # Copy the graph to avoid modifying the original\n    graph = _prepare_for_drawing(graph.copy())\n    sockets = {\n        comp: \"\".join(\n            [\n                f\"<li>{name} ({_type_name(socket.type)})</li>\"\n                for name, socket in data.get(\"input_sockets\", {}).items()\n                if (not socket.is_mandatory and not socket.senders) or socket.is_variadic\n            ]\n        )\n        for comp, data in graph.nodes(data=True)\n    }\n    optional_inputs = {\n        comp: f\"<br><br>Optional inputs:<ul style='text-align:left;'>{sockets}</ul>\" if sockets else \"\"\n        for comp, sockets in sockets.items()\n    }\n\n    states = {\n        comp: f\"{comp}[\\\"<b>{comp}</b><br><small><i>{type(data['instance']).__name__}{optional_inputs[comp]}</i></small>\\\"]:::component\"\n        for comp, data in graph.nodes(data=True)\n        if comp not in [\"input\", \"output\"]\n    }\n\n    connections_list = []\n    for from_comp, to_comp, conn_data in graph.edges(data=True):\n        if from_comp != \"input\" and to_comp != \"output\":\n            arrowtail = ARROWTAIL_MANDATORY if conn_data[\"mandatory\"] else ARROWTAIL_OPTIONAL\n            arrowhead = ARROWHEAD_MANDATORY if conn_data[\"mandatory\"] else ARROWHEAD_OPTIONAL\n            label = f'\"{conn_data[\"label\"]}<br><small><i>{conn_data[\"conn_type\"]}</i></small>\"'\n            conn_string = f\"{states[from_comp]} {arrowtail} {label} {arrowhead} {states[to_comp]}\"\n            connections_list.append(conn_string)\n\n    input_connections = [\n        f\"i{{*}} -- \\\"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\\\" --> {states[to_comp]}\"\n        for _, to_comp, conn_data in graph.out_edges(\"input\", data=True)\n    ]\n    output_connections = [\n        f\"{states[from_comp]} -- \\\"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\\\"--> o{{*}}\"\n        for from_comp, _, conn_data in graph.in_edges(\"output\", data=True)\n    ]\n    connections = \"\\n\".join(connections_list + input_connections + output_connections)\n\n    graph_styled = MERMAID_STYLED_TEMPLATE.format(connections=connections)\n    logger.debug(\"Mermaid diagram:\\n%s\", graph_styled)\n\n    return graph_styled\n", "path": "haystack/core/pipeline/draw.py"}], "after_files": [{"content": "# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>\n#\n# SPDX-License-Identifier: Apache-2.0\nimport base64\nimport logging\n\nimport networkx  # type:ignore\nimport requests\n\nfrom haystack.core.errors import PipelineDrawingError\nfrom haystack.core.pipeline.descriptions import find_pipeline_inputs, find_pipeline_outputs\nfrom haystack.core.type_utils import _type_name\n\nlogger = logging.getLogger(__name__)\n\n\ndef _prepare_for_drawing(graph: networkx.MultiDiGraph) -> networkx.MultiDiGraph:\n    \"\"\"\n    Add some extra nodes to show the inputs and outputs of the pipeline.\n    Also adds labels to edges.\n    \"\"\"\n    # Label the edges\n    for inp, outp, key, data in graph.edges(keys=True, data=True):\n        data[\n            \"label\"\n        ] = f\"{data['from_socket'].name} -> {data['to_socket'].name}{' (opt.)' if not data['mandatory'] else ''}\"\n        graph.add_edge(inp, outp, key=key, **data)\n\n    # Add inputs fake node\n    graph.add_node(\"input\")\n    for node, in_sockets in find_pipeline_inputs(graph).items():\n        for in_socket in in_sockets:\n            if not in_socket.senders and in_socket.is_mandatory:\n                # If this socket has no sender it could be a socket that receives input\n                # directly when running the Pipeline. We can't know that for sure, in doubt\n                # we draw it as receiving input directly.\n                graph.add_edge(\"input\", node, label=in_socket.name, conn_type=_type_name(in_socket.type))\n\n    # Add outputs fake node\n    graph.add_node(\"output\")\n    for node, out_sockets in find_pipeline_outputs(graph).items():\n        for out_socket in out_sockets:\n            graph.add_edge(node, \"output\", label=out_socket.name, conn_type=_type_name(out_socket.type))\n\n    return graph\n\n\nARROWTAIL_MANDATORY = \"--\"\nARROWTAIL_OPTIONAL = \"-.\"\nARROWHEAD_MANDATORY = \"-->\"\nARROWHEAD_OPTIONAL = \".->\"\nMERMAID_STYLED_TEMPLATE = \"\"\"\n%%{{ init: {{'theme': 'neutral' }} }}%%\n\ngraph TD;\n\n{connections}\n\nclassDef component text-align:center;\n\"\"\"\n\n\ndef _to_mermaid_image(graph: networkx.MultiDiGraph):\n    \"\"\"\n    Renders a pipeline using Mermaid (hosted version at 'https://mermaid.ink'). Requires Internet access.\n    \"\"\"\n    # Copy the graph to avoid modifying the original\n    graph_styled = _to_mermaid_text(graph.copy())\n\n    graphbytes = graph_styled.encode(\"ascii\")\n    base64_bytes = base64.b64encode(graphbytes)\n    base64_string = base64_bytes.decode(\"ascii\")\n    url = f\"https://mermaid.ink/img/{base64_string}?type=png\"\n\n    logging.debug(\"Rendeding graph at %s\", url)\n    try:\n        resp = requests.get(url, timeout=10)\n        if resp.status_code >= 400:\n            logger.warning(\"Failed to draw the pipeline: https://mermaid.ink/img/ returned status %s\", resp.status_code)\n            logger.info(\"Exact URL requested: %s\", url)\n            logger.warning(\"No pipeline diagram will be saved.\")\n            resp.raise_for_status()\n\n    except Exception as exc:  # pylint: disable=broad-except\n        logger.warning(\"Failed to draw the pipeline: could not connect to https://mermaid.ink/img/ (%s)\", exc)\n        logger.info(\"Exact URL requested: %s\", url)\n        logger.warning(\"No pipeline diagram will be saved.\")\n        raise PipelineDrawingError(\n            \"There was an issue with https://mermaid.ink/, see the stacktrace for details.\"\n        ) from exc\n\n    return resp.content\n\n\ndef _to_mermaid_text(graph: networkx.MultiDiGraph) -> str:\n    \"\"\"\n    Converts a Networkx graph into Mermaid syntax. The output of this function can be used in the documentation\n    with `mermaid` codeblocks and it will be automatically rendered.\n    \"\"\"\n    # Copy the graph to avoid modifying the original\n    graph = _prepare_for_drawing(graph.copy())\n    sockets = {\n        comp: \"\".join(\n            [\n                f\"<li>{name} ({_type_name(socket.type)})</li>\"\n                for name, socket in data.get(\"input_sockets\", {}).items()\n                if (not socket.is_mandatory and not socket.senders) or socket.is_variadic\n            ]\n        )\n        for comp, data in graph.nodes(data=True)\n    }\n    optional_inputs = {\n        comp: f\"<br><br>Optional inputs:<ul style='text-align:left;'>{sockets}</ul>\" if sockets else \"\"\n        for comp, sockets in sockets.items()\n    }\n\n    states = {\n        comp: f\"{comp}[\\\"<b>{comp}</b><br><small><i>{type(data['instance']).__name__}{optional_inputs[comp]}</i></small>\\\"]:::component\"\n        for comp, data in graph.nodes(data=True)\n        if comp not in [\"input\", \"output\"]\n    }\n\n    connections_list = []\n    for from_comp, to_comp, conn_data in graph.edges(data=True):\n        if from_comp != \"input\" and to_comp != \"output\":\n            arrowtail = ARROWTAIL_MANDATORY if conn_data[\"mandatory\"] else ARROWTAIL_OPTIONAL\n            arrowhead = ARROWHEAD_MANDATORY if conn_data[\"mandatory\"] else ARROWHEAD_OPTIONAL\n            label = f'\"{conn_data[\"label\"]}<br><small><i>{conn_data[\"conn_type\"]}</i></small>\"'\n            conn_string = f\"{states[from_comp]} {arrowtail} {label} {arrowhead} {states[to_comp]}\"\n            connections_list.append(conn_string)\n\n    input_connections = [\n        f\"i{{*}} -- \\\"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\\\" --> {states[to_comp]}\"\n        for _, to_comp, conn_data in graph.out_edges(\"input\", data=True)\n    ]\n    output_connections = [\n        f\"{states[from_comp]} -- \\\"{conn_data['label']}<br><small><i>{conn_data['conn_type']}</i></small>\\\"--> o{{*}}\"\n        for from_comp, _, conn_data in graph.in_edges(\"output\", data=True)\n    ]\n    connections = \"\\n\".join(connections_list + input_connections + output_connections)\n\n    graph_styled = MERMAID_STYLED_TEMPLATE.format(connections=connections)\n    logger.debug(\"Mermaid diagram:\\n%s\", graph_styled)\n\n    return graph_styled\n", "path": "haystack/core/pipeline/draw.py"}]}