We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`HTMLToDocument` to add `ByteStream` metadata to Document 
`HTMLToDocument` converter, when receiving a `ByteStream` from the `LinkContentFetcher` does not add the url to the metadata of the Document. The URL is in the metadata of the ByteStream


--- 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/preview/components/file_converters/html.py`
Content:
```
1 import logging
2 from typing import List, Union
3 from pathlib import Path
4 
5 from haystack.preview import Document, component
6 from haystack.preview.dataclasses import ByteStream
7 from haystack.preview.lazy_imports import LazyImport
8 
9 logger = logging.getLogger(__name__)
10 
11 with LazyImport("Run 'pip install boilerpy3'") as boilerpy3_import:
12     from boilerpy3 import extractors
13 
14 
15 @component
16 class HTMLToDocument:
17     """
18     Converts an HTML file to a Document.
19     """
20 
21     def __init__(self):
22         """
23         Initializes the HTMLToDocument component.
24         """
25         boilerpy3_import.check()
26 
27     @component.output_types(documents=List[Document])
28     def run(self, sources: List[Union[str, Path, ByteStream]]):
29         """
30         Converts a list of HTML files to Documents.
31 
32         :param sources: List of HTML file paths or ByteStream objects.
33         :return: List of converted Documents.
34         """
35         documents = []
36         extractor = extractors.ArticleExtractor(raise_on_failure=False)
37         for source in sources:
38             try:
39                 file_content = self._extract_content(source)
40             except Exception as e:
41                 logger.warning("Could not read %s. Skipping it. Error: %s", source, e)
42                 continue
43             try:
44                 text = extractor.get_content(file_content)
45             except Exception as conversion_e:  # Consider specifying the expected exception type(s) here
46                 logger.warning("Failed to extract text from %s. Skipping it. Error: %s", source, conversion_e)
47                 continue
48 
49             document = Document(content=text)
50             documents.append(document)
51 
52         return {"documents": documents}
53 
54     def _extract_content(self, source: Union[str, Path, ByteStream]) -> str:
55         """
56         Extracts content from the given data source
57         :param source: The data source to extract content from.
58         :return: The extracted content.
59         """
60         if isinstance(source, (str, Path)):
61             with open(source) as text_file:
62                 return text_file.read()
63         if isinstance(source, ByteStream):
64             return source.data.decode("utf-8")
65 
66         raise ValueError(f"Unsupported source type: {type(source)}")
67
```
--- 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/preview/components/file_converters/html.py b/haystack/preview/components/file_converters/html.py
--- a/haystack/preview/components/file_converters/html.py
+++ b/haystack/preview/components/file_converters/html.py
@@ -1,6 +1,6 @@
 import logging
-from typing import List, Union
 from pathlib import Path
+from typing import Any, Dict, List, Optional, Union
 
 from haystack.preview import Document, component
 from haystack.preview.dataclasses import ByteStream
@@ -16,6 +16,18 @@
 class HTMLToDocument:
     """
     Converts an HTML file to a Document.
+
+    Usage example:
+    ```python
+    from haystack.preview.components.file_converters.html import HTMLToDocument
+
+    converter = HTMLToDocument()
+    results = converter.run(sources=["sample.html"])
+    documents = results["documents"]
+    print(documents[0].content)
+    # 'This is a text from the HTML file.'
+    ```
+
     """
 
     def __init__(self):
@@ -25,18 +37,30 @@
         boilerpy3_import.check()
 
     @component.output_types(documents=List[Document])
-    def run(self, sources: List[Union[str, Path, ByteStream]]):
+    def run(self, sources: List[Union[str, Path, ByteStream]], meta: Optional[List[Dict[str, Any]]] = None):
         """
         Converts a list of HTML files to Documents.
 
         :param sources: List of HTML file paths or ByteStream objects.
+        :param meta: Optional list of metadata to attach to the Documents.
+        The length of the list must match the number of sources. Defaults to `None`.
         :return: List of converted Documents.
         """
+
         documents = []
+
+        # Create metadata placeholders if not provided
+        if meta:
+            if len(sources) != len(meta):
+                raise ValueError("The length of the metadata list must match the number of sources.")
+        else:
+            meta = [{}] * len(sources)
+
         extractor = extractors.ArticleExtractor(raise_on_failure=False)
-        for source in sources:
+
+        for source, metadata in zip(sources, meta):
             try:
-                file_content = self._extract_content(source)
+                file_content, extracted_meta = self._extract_content(source)
             except Exception as e:
                 logger.warning("Could not read %s. Skipping it. Error: %s", source, e)
                 continue
@@ -46,21 +70,25 @@
                 logger.warning("Failed to extract text from %s. Skipping it. Error: %s", source, conversion_e)
                 continue
 
-            document = Document(content=text)
+            # Merge metadata received from ByteStream with supplied metadata
+            if extracted_meta:
+                # Supplied metadata overwrites metadata from ByteStream for overlapping keys.
+                metadata = {**extracted_meta, **metadata}
+            document = Document(content=text, meta=metadata)
             documents.append(document)
 
         return {"documents": documents}
 
-    def _extract_content(self, source: Union[str, Path, ByteStream]) -> str:
+    def _extract_content(self, source: Union[str, Path, ByteStream]) -> tuple:
         """
         Extracts content from the given data source
         :param source: The data source to extract content from.
-        :return: The extracted content.
+        :return: The extracted content and metadata.
         """
         if isinstance(source, (str, Path)):
             with open(source) as text_file:
-                return text_file.read()
+                return (text_file.read(), None)
         if isinstance(source, ByteStream):
-            return source.data.decode("utf-8")
+            return (source.data.decode("utf-8"), source.metadata)
 
         raise ValueError(f"Unsupported source type: {type(source)}")

{"golden_diff": "diff --git a/haystack/preview/components/file_converters/html.py b/haystack/preview/components/file_converters/html.py\n--- a/haystack/preview/components/file_converters/html.py\n+++ b/haystack/preview/components/file_converters/html.py\n@@ -1,6 +1,6 @@\n import logging\n-from typing import List, Union\n from pathlib import Path\n+from typing import Any, Dict, List, Optional, Union\n \n from haystack.preview import Document, component\n from haystack.preview.dataclasses import ByteStream\n@@ -16,6 +16,18 @@\n class HTMLToDocument:\n     \"\"\"\n     Converts an HTML file to a Document.\n+\n+    Usage example:\n+    ```python\n+    from haystack.preview.components.file_converters.html import HTMLToDocument\n+\n+    converter = HTMLToDocument()\n+    results = converter.run(sources=[\"sample.html\"])\n+    documents = results[\"documents\"]\n+    print(documents[0].content)\n+    # 'This is a text from the HTML file.'\n+    ```\n+\n     \"\"\"\n \n     def __init__(self):\n@@ -25,18 +37,30 @@\n         boilerpy3_import.check()\n \n     @component.output_types(documents=List[Document])\n-    def run(self, sources: List[Union[str, Path, ByteStream]]):\n+    def run(self, sources: List[Union[str, Path, ByteStream]], meta: Optional[List[Dict[str, Any]]] = None):\n         \"\"\"\n         Converts a list of HTML files to Documents.\n \n         :param sources: List of HTML file paths or ByteStream objects.\n+        :param meta: Optional list of metadata to attach to the Documents.\n+        The length of the list must match the number of sources. Defaults to `None`.\n         :return: List of converted Documents.\n         \"\"\"\n+\n         documents = []\n+\n+        # Create metadata placeholders if not provided\n+        if meta:\n+            if len(sources) != len(meta):\n+                raise ValueError(\"The length of the metadata list must match the number of sources.\")\n+        else:\n+            meta = [{}] * len(sources)\n+\n         extractor = extractors.ArticleExtractor(raise_on_failure=False)\n-        for source in sources:\n+\n+        for source, metadata in zip(sources, meta):\n             try:\n-                file_content = self._extract_content(source)\n+                file_content, extracted_meta = self._extract_content(source)\n             except Exception as e:\n                 logger.warning(\"Could not read %s. Skipping it. Error: %s\", source, e)\n                 continue\n@@ -46,21 +70,25 @@\n                 logger.warning(\"Failed to extract text from %s. Skipping it. Error: %s\", source, conversion_e)\n                 continue\n \n-            document = Document(content=text)\n+            # Merge metadata received from ByteStream with supplied metadata\n+            if extracted_meta:\n+                # Supplied metadata overwrites metadata from ByteStream for overlapping keys.\n+                metadata = {**extracted_meta, **metadata}\n+            document = Document(content=text, meta=metadata)\n             documents.append(document)\n \n         return {\"documents\": documents}\n \n-    def _extract_content(self, source: Union[str, Path, ByteStream]) -> str:\n+    def _extract_content(self, source: Union[str, Path, ByteStream]) -> tuple:\n         \"\"\"\n         Extracts content from the given data source\n         :param source: The data source to extract content from.\n-        :return: The extracted content.\n+        :return: The extracted content and metadata.\n         \"\"\"\n         if isinstance(source, (str, Path)):\n             with open(source) as text_file:\n-                return text_file.read()\n+                return (text_file.read(), None)\n         if isinstance(source, ByteStream):\n-            return source.data.decode(\"utf-8\")\n+            return (source.data.decode(\"utf-8\"), source.metadata)\n \n         raise ValueError(f\"Unsupported source type: {type(source)}\")\n", "issue": "`HTMLToDocument` to add `ByteStream` metadata to Document \n`HTMLToDocument` converter, when receiving a `ByteStream` from the `LinkContentFetcher` does not add the url to the metadata of the Document. The URL is in the metadata of the ByteStream\r\n\n", "before_files": [{"content": "import logging\nfrom typing import List, Union\nfrom pathlib import Path\n\nfrom haystack.preview import Document, component\nfrom haystack.preview.dataclasses import ByteStream\nfrom haystack.preview.lazy_imports import LazyImport\n\nlogger = logging.getLogger(__name__)\n\nwith LazyImport(\"Run 'pip install boilerpy3'\") as boilerpy3_import:\n    from boilerpy3 import extractors\n\n\n@component\nclass HTMLToDocument:\n    \"\"\"\n    Converts an HTML file to a Document.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Initializes the HTMLToDocument component.\n        \"\"\"\n        boilerpy3_import.check()\n\n    @component.output_types(documents=List[Document])\n    def run(self, sources: List[Union[str, Path, ByteStream]]):\n        \"\"\"\n        Converts a list of HTML files to Documents.\n\n        :param sources: List of HTML file paths or ByteStream objects.\n        :return: List of converted Documents.\n        \"\"\"\n        documents = []\n        extractor = extractors.ArticleExtractor(raise_on_failure=False)\n        for source in sources:\n            try:\n                file_content = self._extract_content(source)\n            except Exception as e:\n                logger.warning(\"Could not read %s. Skipping it. Error: %s\", source, e)\n                continue\n            try:\n                text = extractor.get_content(file_content)\n            except Exception as conversion_e:  # Consider specifying the expected exception type(s) here\n                logger.warning(\"Failed to extract text from %s. Skipping it. Error: %s\", source, conversion_e)\n                continue\n\n            document = Document(content=text)\n            documents.append(document)\n\n        return {\"documents\": documents}\n\n    def _extract_content(self, source: Union[str, Path, ByteStream]) -> str:\n        \"\"\"\n        Extracts content from the given data source\n        :param source: The data source to extract content from.\n        :return: The extracted content.\n        \"\"\"\n        if isinstance(source, (str, Path)):\n            with open(source) as text_file:\n                return text_file.read()\n        if isinstance(source, ByteStream):\n            return source.data.decode(\"utf-8\")\n\n        raise ValueError(f\"Unsupported source type: {type(source)}\")\n", "path": "haystack/preview/components/file_converters/html.py"}], "after_files": [{"content": "import logging\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom haystack.preview import Document, component\nfrom haystack.preview.dataclasses import ByteStream\nfrom haystack.preview.lazy_imports import LazyImport\n\nlogger = logging.getLogger(__name__)\n\nwith LazyImport(\"Run 'pip install boilerpy3'\") as boilerpy3_import:\n    from boilerpy3 import extractors\n\n\n@component\nclass HTMLToDocument:\n    \"\"\"\n    Converts an HTML file to a Document.\n\n    Usage example:\n    ```python\n    from haystack.preview.components.file_converters.html import HTMLToDocument\n\n    converter = HTMLToDocument()\n    results = converter.run(sources=[\"sample.html\"])\n    documents = results[\"documents\"]\n    print(documents[0].content)\n    # 'This is a text from the HTML file.'\n    ```\n\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Initializes the HTMLToDocument component.\n        \"\"\"\n        boilerpy3_import.check()\n\n    @component.output_types(documents=List[Document])\n    def run(self, sources: List[Union[str, Path, ByteStream]], meta: Optional[List[Dict[str, Any]]] = None):\n        \"\"\"\n        Converts a list of HTML files to Documents.\n\n        :param sources: List of HTML file paths or ByteStream objects.\n        :param meta: Optional list of metadata to attach to the Documents.\n        The length of the list must match the number of sources. Defaults to `None`.\n        :return: List of converted Documents.\n        \"\"\"\n\n        documents = []\n\n        # Create metadata placeholders if not provided\n        if meta:\n            if len(sources) != len(meta):\n                raise ValueError(\"The length of the metadata list must match the number of sources.\")\n        else:\n            meta = [{}] * len(sources)\n\n        extractor = extractors.ArticleExtractor(raise_on_failure=False)\n\n        for source, metadata in zip(sources, meta):\n            try:\n                file_content, extracted_meta = self._extract_content(source)\n            except Exception as e:\n                logger.warning(\"Could not read %s. Skipping it. Error: %s\", source, e)\n                continue\n            try:\n                text = extractor.get_content(file_content)\n            except Exception as conversion_e:  # Consider specifying the expected exception type(s) here\n                logger.warning(\"Failed to extract text from %s. Skipping it. Error: %s\", source, conversion_e)\n                continue\n\n            # Merge metadata received from ByteStream with supplied metadata\n            if extracted_meta:\n                # Supplied metadata overwrites metadata from ByteStream for overlapping keys.\n                metadata = {**extracted_meta, **metadata}\n            document = Document(content=text, meta=metadata)\n            documents.append(document)\n\n        return {\"documents\": documents}\n\n    def _extract_content(self, source: Union[str, Path, ByteStream]) -> tuple:\n        \"\"\"\n        Extracts content from the given data source\n        :param source: The data source to extract content from.\n        :return: The extracted content and metadata.\n        \"\"\"\n        if isinstance(source, (str, Path)):\n            with open(source) as text_file:\n                return (text_file.read(), None)\n        if isinstance(source, ByteStream):\n            return (source.data.decode(\"utf-8\"), source.metadata)\n\n        raise ValueError(f\"Unsupported source type: {type(source)}\")\n", "path": "haystack/preview/components/file_converters/html.py"}]}