We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
REST API fails when embeddings returned flag is enabled in document store
Good morning Haystack devs. Not sure if this is really a bug or I'm doing something wrong, so feel free to change the type if this issue to something else if it's not a bug.

**Describe the bug**
When the document store is forced to return the embeddings the REST API request fails because the type of the embedding is a Numpy array (`dtype=float32`) but the Pydantic dataclass of `DocumentSerialized` expects a `List[float]` and I think there is no automatic conversion between both types.

**Error message**
```
[2021-11-26 08:48:59 +0000] [10] [ERROR] Exception in ASGI application
haystack-api_1  | Traceback (most recent call last):
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
haystack-api_1  |     result = await app(self.scope, self.receive, self.send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
haystack-api_1  |     return await self.app(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/fastapi/applications.py", line 208, in __call__
haystack-api_1  |     await super().__call__(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/applications.py", line 112, in __call__
haystack-api_1  |     await self.middleware_stack(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py", line 181, in __call__
haystack-api_1  |     raise exc
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py", line 159, in __call__
haystack-api_1  |     await self.app(scope, receive, _send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/cors.py", line 84, in __call__
haystack-api_1  |     await self.app(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py", line 82, in __call__
haystack-api_1  |     raise exc
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py", line 71, in __call__
haystack-api_1  |     await self.app(scope, receive, sender)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 656, in __call__
haystack-api_1  |     await route.handle(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 259, in handle
haystack-api_1  |     await self.app(scope, receive, send)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 61, in app
haystack-api_1  |     response = await func(request)
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/fastapi/routing.py", line 243, in app
haystack-api_1  |     is_coroutine=is_coroutine,
haystack-api_1  |   File "/usr/local/lib/python3.7/dist-packages/fastapi/routing.py", line 137, in serialize_response
haystack-api_1  |     raise ValidationError(errors, field.type_)
haystack-api_1  | pydantic.error_wrappers.ValidationError: 5 validation errors for QueryResponse
haystack-api_1  | response -> documents -> 0 -> embedding
haystack-api_1  |   value is not a valid list (type=type_error.list)
haystack-api_1  | response -> documents -> 1 -> embedding
haystack-api_1  |   value is not a valid list (type=type_error.list)
haystack-api_1  | response -> documents -> 2 -> embedding
haystack-api_1  |   value is not a valid list (type=type_error.list)
haystack-api_1  | response -> documents -> 3 -> embedding
haystack-api_1  |   value is not a valid list (type=type_error.list)
haystack-api_1  | response -> documents -> 4 -> embedding
haystack-api_1  |   value is not a valid list (type=type_error.list)
```


**To Reproduce**
Just start the REST API with `return_embedding: True` set in the document store

**System:**
 - Haystack version (commit or version number): 1.0RC1 (latest version from Github)
 - DocumentStore: Milvus
 - Reader: Farm
 - Retriever: DPR


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `rest_api/controller/search.py`
Content:
```
1 import logging
2 import time
3 import json
4 from pathlib import Path
5 
6 from fastapi import APIRouter
7 
8 import haystack
9 from haystack.pipelines.base import Pipeline
10 from rest_api.config import PIPELINE_YAML_PATH, QUERY_PIPELINE_NAME
11 from rest_api.config import LOG_LEVEL, CONCURRENT_REQUEST_PER_WORKER
12 from rest_api.schema import QueryRequest, QueryResponse
13 from rest_api.controller.utils import RequestLimiter
14 
15 
16 logging.getLogger("haystack").setLevel(LOG_LEVEL)
17 logger = logging.getLogger("haystack")
18 
19 from pydantic import BaseConfig
20 
21 BaseConfig.arbitrary_types_allowed = True
22 
23 router = APIRouter()
24 
25 
26 PIPELINE = Pipeline.load_from_yaml(Path(PIPELINE_YAML_PATH), pipeline_name=QUERY_PIPELINE_NAME)
27 # TODO make this generic for other pipelines with different naming
28 RETRIEVER = PIPELINE.get_node(name="Retriever")
29 DOCUMENT_STORE = RETRIEVER.document_store if RETRIEVER else None
30 logging.info(f"Loaded pipeline nodes: {PIPELINE.graph.nodes.keys()}")
31 
32 concurrency_limiter = RequestLimiter(CONCURRENT_REQUEST_PER_WORKER)
33 logging.info("Concurrent requests per worker: {CONCURRENT_REQUEST_PER_WORKER}")
34 
35 
36 @router.get("/initialized")
37 def check_status():
38     """
39     This endpoint can be used during startup to understand if the 
40     server is ready to take any requests, or is still loading.
41 
42     The recommended approach is to call this endpoint with a short timeout,
43     like 500ms, and in case of no reply, consider the server busy.
44     """
45     return True
46 
47 
48 @router.get("/hs_version")
49 def haystack_version():
50     return {"hs_version": haystack.__version__}
51 
52 
53 @router.post("/query", response_model=QueryResponse, response_model_exclude_none=True)
54 def query(request: QueryRequest):
55     with concurrency_limiter.run():
56         result = _process_request(PIPELINE, request)
57         return result
58 
59 
60 def _process_request(pipeline, request) -> QueryResponse:
61     start_time = time.time()
62     
63     params = request.params or {}
64 
65     # format global, top-level filters (e.g. "params": {"filters": {"name": ["some"]}})
66     if "filters" in params.keys():
67         params["filters"] = _format_filters(params["filters"])
68 
69     # format targeted node filters (e.g. "params": {"Retriever": {"filters": {"value"}}})
70     for key, value in params.items():
71         if "filters" in params[key].keys():
72             params[key]["filters"] = _format_filters(params[key]["filters"])
73 
74     result = pipeline.run(query=request.query, params=params,debug=request.debug)
75     end_time = time.time()
76     logger.info(json.dumps({"request": request, "response": result, "time": f"{(end_time - start_time):.2f}"}, default=str))
77 
78     return result
79 
80 
81 def _format_filters(filters):
82     """
83     Adjust filters to compliant format:
84     Put filter values into a list and remove filters with null value.
85     """
86     new_filters = {}
87     if filters is None:
88         logger.warning(f"Request with deprecated filter format ('\"filters\": null'). "
89                        f"Remove empty filters from params to be compliant with future versions")
90     else:
91         for key, values in filters.items():
92             if values is None:
93                 logger.warning(f"Request with deprecated filter format ('{key}: null'). "
94                                f"Remove null values from filters to be compliant with future versions")
95                 continue
96             elif not isinstance(values, list):
97                 logger.warning(f"Request with deprecated filter format ('{key}': {values}). "
98                                f"Change to '{key}':[{values}]' to be compliant with future versions")
99                 values = [values]
100 
101             new_filters[key] = values
102     return new_filters
103
```
--- 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/rest_api/controller/search.py b/rest_api/controller/search.py
--- a/rest_api/controller/search.py
+++ b/rest_api/controller/search.py
@@ -2,6 +2,7 @@
 import time
 import json
 from pathlib import Path
+from numpy import ndarray
 
 from fastapi import APIRouter
 
@@ -72,6 +73,12 @@
             params[key]["filters"] = _format_filters(params[key]["filters"])
 
     result = pipeline.run(query=request.query, params=params,debug=request.debug)
+    
+    # if any of the documents contains an embedding as an ndarray the latter needs to be converted to list of float
+    for document in result['documents'] or []:
+        if isinstance(document.embedding, ndarray):
+            document.embedding = document.embedding.tolist()
+    
     end_time = time.time()
     logger.info(json.dumps({"request": request, "response": result, "time": f"{(end_time - start_time):.2f}"}, default=str))

{"golden_diff": "diff --git a/rest_api/controller/search.py b/rest_api/controller/search.py\n--- a/rest_api/controller/search.py\n+++ b/rest_api/controller/search.py\n@@ -2,6 +2,7 @@\n import time\n import json\n from pathlib import Path\n+from numpy import ndarray\n \n from fastapi import APIRouter\n \n@@ -72,6 +73,12 @@\n             params[key][\"filters\"] = _format_filters(params[key][\"filters\"])\n \n     result = pipeline.run(query=request.query, params=params,debug=request.debug)\n+    \n+    # if any of the documents contains an embedding as an ndarray the latter needs to be converted to list of float\n+    for document in result['documents'] or []:\n+        if isinstance(document.embedding, ndarray):\n+            document.embedding = document.embedding.tolist()\n+    \n     end_time = time.time()\n     logger.info(json.dumps({\"request\": request, \"response\": result, \"time\": f\"{(end_time - start_time):.2f}\"}, default=str))\n", "issue": "REST API fails when embeddings returned flag is enabled in document store\nGood morning Haystack devs. Not sure if this is really a bug or I'm doing something wrong, so feel free to change the type if this issue to something else if it's not a bug.\r\n\r\n**Describe the bug**\r\nWhen the document store is forced to return the embeddings the REST API request fails because the type of the embedding is a Numpy array (`dtype=float32`) but the Pydantic dataclass of `DocumentSerialized` expects a `List[float]` and I think there is no automatic conversion between both types.\r\n\r\n**Error message**\r\n```\r\n[2021-11-26 08:48:59 +0000] [10] [ERROR] Exception in ASGI application\r\nhaystack-api_1  | Traceback (most recent call last):\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/uvicorn/protocols/http/httptools_impl.py\", line 375, in run_asgi\r\nhaystack-api_1  |     result = await app(self.scope, self.receive, self.send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__\r\nhaystack-api_1  |     return await self.app(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/fastapi/applications.py\", line 208, in __call__\r\nhaystack-api_1  |     await super().__call__(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/applications.py\", line 112, in __call__\r\nhaystack-api_1  |     await self.middleware_stack(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py\", line 181, in __call__\r\nhaystack-api_1  |     raise exc\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py\", line 159, in __call__\r\nhaystack-api_1  |     await self.app(scope, receive, _send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/middleware/cors.py\", line 84, in __call__\r\nhaystack-api_1  |     await self.app(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py\", line 82, in __call__\r\nhaystack-api_1  |     raise exc\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py\", line 71, in __call__\r\nhaystack-api_1  |     await self.app(scope, receive, sender)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/routing.py\", line 656, in __call__\r\nhaystack-api_1  |     await route.handle(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/routing.py\", line 259, in handle\r\nhaystack-api_1  |     await self.app(scope, receive, send)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/starlette/routing.py\", line 61, in app\r\nhaystack-api_1  |     response = await func(request)\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/fastapi/routing.py\", line 243, in app\r\nhaystack-api_1  |     is_coroutine=is_coroutine,\r\nhaystack-api_1  |   File \"/usr/local/lib/python3.7/dist-packages/fastapi/routing.py\", line 137, in serialize_response\r\nhaystack-api_1  |     raise ValidationError(errors, field.type_)\r\nhaystack-api_1  | pydantic.error_wrappers.ValidationError: 5 validation errors for QueryResponse\r\nhaystack-api_1  | response -> documents -> 0 -> embedding\r\nhaystack-api_1  |   value is not a valid list (type=type_error.list)\r\nhaystack-api_1  | response -> documents -> 1 -> embedding\r\nhaystack-api_1  |   value is not a valid list (type=type_error.list)\r\nhaystack-api_1  | response -> documents -> 2 -> embedding\r\nhaystack-api_1  |   value is not a valid list (type=type_error.list)\r\nhaystack-api_1  | response -> documents -> 3 -> embedding\r\nhaystack-api_1  |   value is not a valid list (type=type_error.list)\r\nhaystack-api_1  | response -> documents -> 4 -> embedding\r\nhaystack-api_1  |   value is not a valid list (type=type_error.list)\r\n```\r\n\r\n\r\n**To Reproduce**\r\nJust start the REST API with `return_embedding: True` set in the document store\r\n\r\n**System:**\r\n - Haystack version (commit or version number): 1.0RC1 (latest version from Github)\r\n - DocumentStore: Milvus\r\n - Reader: Farm\r\n - Retriever: DPR\r\n\n", "before_files": [{"content": "import logging\nimport time\nimport json\nfrom pathlib import Path\n\nfrom fastapi import APIRouter\n\nimport haystack\nfrom haystack.pipelines.base import Pipeline\nfrom rest_api.config import PIPELINE_YAML_PATH, QUERY_PIPELINE_NAME\nfrom rest_api.config import LOG_LEVEL, CONCURRENT_REQUEST_PER_WORKER\nfrom rest_api.schema import QueryRequest, QueryResponse\nfrom rest_api.controller.utils import RequestLimiter\n\n\nlogging.getLogger(\"haystack\").setLevel(LOG_LEVEL)\nlogger = logging.getLogger(\"haystack\")\n\nfrom pydantic import BaseConfig\n\nBaseConfig.arbitrary_types_allowed = True\n\nrouter = APIRouter()\n\n\nPIPELINE = Pipeline.load_from_yaml(Path(PIPELINE_YAML_PATH), pipeline_name=QUERY_PIPELINE_NAME)\n# TODO make this generic for other pipelines with different naming\nRETRIEVER = PIPELINE.get_node(name=\"Retriever\")\nDOCUMENT_STORE = RETRIEVER.document_store if RETRIEVER else None\nlogging.info(f\"Loaded pipeline nodes: {PIPELINE.graph.nodes.keys()}\")\n\nconcurrency_limiter = RequestLimiter(CONCURRENT_REQUEST_PER_WORKER)\nlogging.info(\"Concurrent requests per worker: {CONCURRENT_REQUEST_PER_WORKER}\")\n\n\n@router.get(\"/initialized\")\ndef check_status():\n    \"\"\"\n    This endpoint can be used during startup to understand if the \n    server is ready to take any requests, or is still loading.\n\n    The recommended approach is to call this endpoint with a short timeout,\n    like 500ms, and in case of no reply, consider the server busy.\n    \"\"\"\n    return True\n\n\n@router.get(\"/hs_version\")\ndef haystack_version():\n    return {\"hs_version\": haystack.__version__}\n\n\n@router.post(\"/query\", response_model=QueryResponse, response_model_exclude_none=True)\ndef query(request: QueryRequest):\n    with concurrency_limiter.run():\n        result = _process_request(PIPELINE, request)\n        return result\n\n\ndef _process_request(pipeline, request) -> QueryResponse:\n    start_time = time.time()\n    \n    params = request.params or {}\n\n    # format global, top-level filters (e.g. \"params\": {\"filters\": {\"name\": [\"some\"]}})\n    if \"filters\" in params.keys():\n        params[\"filters\"] = _format_filters(params[\"filters\"])\n\n    # format targeted node filters (e.g. \"params\": {\"Retriever\": {\"filters\": {\"value\"}}})\n    for key, value in params.items():\n        if \"filters\" in params[key].keys():\n            params[key][\"filters\"] = _format_filters(params[key][\"filters\"])\n\n    result = pipeline.run(query=request.query, params=params,debug=request.debug)\n    end_time = time.time()\n    logger.info(json.dumps({\"request\": request, \"response\": result, \"time\": f\"{(end_time - start_time):.2f}\"}, default=str))\n\n    return result\n\n\ndef _format_filters(filters):\n    \"\"\"\n    Adjust filters to compliant format:\n    Put filter values into a list and remove filters with null value.\n    \"\"\"\n    new_filters = {}\n    if filters is None:\n        logger.warning(f\"Request with deprecated filter format ('\\\"filters\\\": null'). \"\n                       f\"Remove empty filters from params to be compliant with future versions\")\n    else:\n        for key, values in filters.items():\n            if values is None:\n                logger.warning(f\"Request with deprecated filter format ('{key}: null'). \"\n                               f\"Remove null values from filters to be compliant with future versions\")\n                continue\n            elif not isinstance(values, list):\n                logger.warning(f\"Request with deprecated filter format ('{key}': {values}). \"\n                               f\"Change to '{key}':[{values}]' to be compliant with future versions\")\n                values = [values]\n\n            new_filters[key] = values\n    return new_filters\n", "path": "rest_api/controller/search.py"}], "after_files": [{"content": "import logging\nimport time\nimport json\nfrom pathlib import Path\nfrom numpy import ndarray\n\nfrom fastapi import APIRouter\n\nimport haystack\nfrom haystack.pipelines.base import Pipeline\nfrom rest_api.config import PIPELINE_YAML_PATH, QUERY_PIPELINE_NAME\nfrom rest_api.config import LOG_LEVEL, CONCURRENT_REQUEST_PER_WORKER\nfrom rest_api.schema import QueryRequest, QueryResponse\nfrom rest_api.controller.utils import RequestLimiter\n\n\nlogging.getLogger(\"haystack\").setLevel(LOG_LEVEL)\nlogger = logging.getLogger(\"haystack\")\n\nfrom pydantic import BaseConfig\n\nBaseConfig.arbitrary_types_allowed = True\n\nrouter = APIRouter()\n\n\nPIPELINE = Pipeline.load_from_yaml(Path(PIPELINE_YAML_PATH), pipeline_name=QUERY_PIPELINE_NAME)\n# TODO make this generic for other pipelines with different naming\nRETRIEVER = PIPELINE.get_node(name=\"Retriever\")\nDOCUMENT_STORE = RETRIEVER.document_store if RETRIEVER else None\nlogging.info(f\"Loaded pipeline nodes: {PIPELINE.graph.nodes.keys()}\")\n\nconcurrency_limiter = RequestLimiter(CONCURRENT_REQUEST_PER_WORKER)\nlogging.info(\"Concurrent requests per worker: {CONCURRENT_REQUEST_PER_WORKER}\")\n\n\n@router.get(\"/initialized\")\ndef check_status():\n    \"\"\"\n    This endpoint can be used during startup to understand if the \n    server is ready to take any requests, or is still loading.\n\n    The recommended approach is to call this endpoint with a short timeout,\n    like 500ms, and in case of no reply, consider the server busy.\n    \"\"\"\n    return True\n\n\n@router.get(\"/hs_version\")\ndef haystack_version():\n    return {\"hs_version\": haystack.__version__}\n\n\n@router.post(\"/query\", response_model=QueryResponse, response_model_exclude_none=True)\ndef query(request: QueryRequest):\n    with concurrency_limiter.run():\n        result = _process_request(PIPELINE, request)\n        return result\n\n\ndef _process_request(pipeline, request) -> QueryResponse:\n    start_time = time.time()\n    \n    params = request.params or {}\n\n    # format global, top-level filters (e.g. \"params\": {\"filters\": {\"name\": [\"some\"]}})\n    if \"filters\" in params.keys():\n        params[\"filters\"] = _format_filters(params[\"filters\"])\n\n    # format targeted node filters (e.g. \"params\": {\"Retriever\": {\"filters\": {\"value\"}}})\n    for key, value in params.items():\n        if \"filters\" in params[key].keys():\n            params[key][\"filters\"] = _format_filters(params[key][\"filters\"])\n\n    result = pipeline.run(query=request.query, params=params,debug=request.debug)\n    \n    # if any of the documents contains an embedding as an ndarray the latter needs to be converted to list of float\n    for document in result['documents'] or []:\n        if isinstance(document.embedding, ndarray):\n            document.embedding = document.embedding.tolist()\n    \n    end_time = time.time()\n    logger.info(json.dumps({\"request\": request, \"response\": result, \"time\": f\"{(end_time - start_time):.2f}\"}, default=str))\n\n    return result\n\n\ndef _format_filters(filters):\n    \"\"\"\n    Adjust filters to compliant format:\n    Put filter values into a list and remove filters with null value.\n    \"\"\"\n    new_filters = {}\n    if filters is None:\n        logger.warning(f\"Request with deprecated filter format ('\\\"filters\\\": null'). \"\n                       f\"Remove empty filters from params to be compliant with future versions\")\n    else:\n        for key, values in filters.items():\n            if values is None:\n                logger.warning(f\"Request with deprecated filter format ('{key}: null'). \"\n                               f\"Remove null values from filters to be compliant with future versions\")\n                continue\n            elif not isinstance(values, list):\n                logger.warning(f\"Request with deprecated filter format ('{key}': {values}). \"\n                               f\"Change to '{key}':[{values}]' to be compliant with future versions\")\n                values = [values]\n\n            new_filters[key] = values\n    return new_filters\n", "path": "rest_api/controller/search.py"}]}