mirror of
				https://github.com/deepset-ai/haystack.git
				synced 2022-02-20 23:31:40 +03:00 
			
		
		
		
	Fix bug on REST API for queries on empty document stores (#2161)
* Handle no answers and no documents scenarios in '_process_request' * Fix tests * Change return type in '_process_request' * Return to use dicts Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
		@@ -755,8 +755,7 @@
 | 
			
		||||
            "QueryResponse": {
 | 
			
		||||
                "title": "QueryResponse",
 | 
			
		||||
                "required": [
 | 
			
		||||
                    "query",
 | 
			
		||||
                    "answers"
 | 
			
		||||
                    "query"
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "object",
 | 
			
		||||
                "properties": {
 | 
			
		||||
@@ -769,14 +768,16 @@
 | 
			
		||||
                        "type": "array",
 | 
			
		||||
                        "items": {
 | 
			
		||||
                            "$ref": "#/components/schemas/AnswerSerialized"
 | 
			
		||||
                        }
 | 
			
		||||
                        },
 | 
			
		||||
                        "default": []
 | 
			
		||||
                    },
 | 
			
		||||
                    "documents": {
 | 
			
		||||
                        "title": "Documents",
 | 
			
		||||
                        "type": "array",
 | 
			
		||||
                        "items": {
 | 
			
		||||
                            "$ref": "#/components/schemas/DocumentSerialized"
 | 
			
		||||
                        }
 | 
			
		||||
                        },
 | 
			
		||||
                        "default": []
 | 
			
		||||
                    },
 | 
			
		||||
                    "_debug": {
 | 
			
		||||
                        "title": " Debug",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
from typing import Dict, Any
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
import time
 | 
			
		||||
import json
 | 
			
		||||
@@ -65,7 +67,7 @@ def query(request: QueryRequest):
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _process_request(pipeline, request) -> QueryResponse:
 | 
			
		||||
def _process_request(pipeline, request) -> Dict[str, Any]:
 | 
			
		||||
    start_time = time.time()
 | 
			
		||||
 | 
			
		||||
    params = request.params or {}
 | 
			
		||||
@@ -75,22 +77,26 @@ def _process_request(pipeline, request) -> QueryResponse:
 | 
			
		||||
        params["filters"] = _format_filters(params["filters"])
 | 
			
		||||
 | 
			
		||||
    # format targeted node filters (e.g. "params": {"Retriever": {"filters": {"value"}}})
 | 
			
		||||
    for key, value in params.items():
 | 
			
		||||
    for key in params.keys():
 | 
			
		||||
        if "filters" in params[key].keys():
 | 
			
		||||
            params[key]["filters"] = _format_filters(params[key]["filters"])
 | 
			
		||||
 | 
			
		||||
    result = pipeline.run(query=request.query, params=params, debug=request.debug)
 | 
			
		||||
 | 
			
		||||
    # Ensure answers and documents exist, even if they're empty lists
 | 
			
		||||
    if not "documents" in result:
 | 
			
		||||
        result["documents"] = []
 | 
			
		||||
    if not "answers" in result:
 | 
			
		||||
        result["answers"] = []
 | 
			
		||||
 | 
			
		||||
    # 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 []:
 | 
			
		||||
    for document in result["documents"]:
 | 
			
		||||
        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)
 | 
			
		||||
        json.dumps({"request": request, "response": result, "time": f"{(time.time() - start_time):.2f}"}, default=str)
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,6 @@ class CreateLabelSerialized(BaseModel):
 | 
			
		||||
 | 
			
		||||
class QueryResponse(BaseModel):
 | 
			
		||||
    query: str
 | 
			
		||||
    answers: List[AnswerSerialized]
 | 
			
		||||
    documents: Optional[List[DocumentSerialized]]
 | 
			
		||||
    answers: List[AnswerSerialized] = []
 | 
			
		||||
    documents: List[DocumentSerialized] = []
 | 
			
		||||
    debug: Optional[Dict] = Field(None, alias="_debug")
 | 
			
		||||
 
 | 
			
		||||
@@ -225,6 +225,23 @@ def test_query_with_invalid_filter(populated_client: TestClient):
 | 
			
		||||
    assert len(response_json["answers"]) == 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_query_with_no_documents_and_no_answers():
 | 
			
		||||
    os.environ["PIPELINE_YAML_PATH"] = str(
 | 
			
		||||
        (Path(__file__).parent / "samples" / "pipeline" / "test_pipeline.yaml").absolute()
 | 
			
		||||
    )
 | 
			
		||||
    os.environ["INDEXING_PIPELINE_NAME"] = "indexing_text_pipeline"
 | 
			
		||||
    client = TestClient(app)
 | 
			
		||||
 | 
			
		||||
    # Clean up to make sure the docstore is empty
 | 
			
		||||
    client.post(url="/documents/delete_by_filters", data='{"filters": {}}')
 | 
			
		||||
    query = {"query": "Who made the PDF specification?"}
 | 
			
		||||
    response = client.post(url="/query", json=query)
 | 
			
		||||
    assert 200 == response.status_code
 | 
			
		||||
    response_json = response.json()
 | 
			
		||||
    assert response_json["documents"] == []
 | 
			
		||||
    assert response_json["answers"] == []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_write_feedback(populated_client: TestClient):
 | 
			
		||||
    response = populated_client.post(url="/feedback", json=FEEDBACK)
 | 
			
		||||
    assert 200 == response.status_code
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user