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:
Sara Zan 2022-02-16 11:10:59 +01:00 committed by GitHub
parent 00795bd71e
commit 13a9bc6a99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 12 deletions

View File

@ -755,8 +755,7 @@
"QueryResponse": { "QueryResponse": {
"title": "QueryResponse", "title": "QueryResponse",
"required": [ "required": [
"query", "query"
"answers"
], ],
"type": "object", "type": "object",
"properties": { "properties": {
@ -769,14 +768,16 @@
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/AnswerSerialized" "$ref": "#/components/schemas/AnswerSerialized"
} },
"default": []
}, },
"documents": { "documents": {
"title": "Documents", "title": "Documents",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/DocumentSerialized" "$ref": "#/components/schemas/DocumentSerialized"
} },
"default": []
}, },
"_debug": { "_debug": {
"title": " Debug", "title": " Debug",

View File

@ -1,3 +1,5 @@
from typing import Dict, Any
import logging import logging
import time import time
import json import json
@ -65,7 +67,7 @@ def query(request: QueryRequest):
return result return result
def _process_request(pipeline, request) -> QueryResponse: def _process_request(pipeline, request) -> Dict[str, Any]:
start_time = time.time() start_time = time.time()
params = request.params or {} params = request.params or {}
@ -75,22 +77,26 @@ def _process_request(pipeline, request) -> QueryResponse:
params["filters"] = _format_filters(params["filters"]) params["filters"] = _format_filters(params["filters"])
# format targeted node filters (e.g. "params": {"Retriever": {"filters": {"value"}}}) # 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(): if "filters" in params[key].keys():
params[key]["filters"] = _format_filters(params[key]["filters"]) params[key]["filters"] = _format_filters(params[key]["filters"])
result = pipeline.run(query=request.query, params=params, debug=request.debug) 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 # 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): if isinstance(document.embedding, ndarray):
document.embedding = document.embedding.tolist() document.embedding = document.embedding.tolist()
end_time = time.time()
logger.info( 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 return result

View File

@ -66,6 +66,6 @@ class CreateLabelSerialized(BaseModel):
class QueryResponse(BaseModel): class QueryResponse(BaseModel):
query: str query: str
answers: List[AnswerSerialized] answers: List[AnswerSerialized] = []
documents: Optional[List[DocumentSerialized]] documents: List[DocumentSerialized] = []
debug: Optional[Dict] = Field(None, alias="_debug") debug: Optional[Dict] = Field(None, alias="_debug")

View File

@ -225,6 +225,23 @@ def test_query_with_invalid_filter(populated_client: TestClient):
assert len(response_json["answers"]) == 0 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): def test_write_feedback(populated_client: TestClient):
response = populated_client.post(url="/feedback", json=FEEDBACK) response = populated_client.post(url="/feedback", json=FEEDBACK)
assert 200 == response.status_code assert 200 == response.status_code