From 619d52592e2239ac85f6b9e949096acb32ae6b0b Mon Sep 17 00:00:00 2001 From: Florian Hardow Date: Sun, 12 Mar 2023 14:53:24 +0100 Subject: [PATCH 1/6] feat: break retry loop for 401 unauthorized errors in promptnode --- haystack/errors.py | 19 +++++++++++++++++++ .../nodes/retriever/_embedding_encoder.py | 4 +++- haystack/utils/openai_utils.py | 4 +++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/haystack/errors.py b/haystack/errors.py index ab17d3fd78..c6150e2b81 100644 --- a/haystack/errors.py +++ b/haystack/errors.py @@ -148,6 +148,16 @@ def __init__(self, message: Optional[str] = None, send_message_in_event: bool = super().__init__(message=message, status_code=429, send_message_in_event=send_message_in_event) +class OpenAIUnauthorizedError(OpenAIError): + """ + Unauthorized error for OpenAI API (status code 401) + See https://platform.openai.com/docs/guides/error-codes/api-errors + """ + + def __init__(self, message: Optional[str] = None, send_message_in_event: bool = False): + super().__init__(message=message, status_code=401, send_message_in_event=send_message_in_event) + + class CohereError(NodeError): """Exception for issues that occur in the Cohere APIs""" @@ -158,6 +168,15 @@ def __init__( self.status_code = status_code +class CohereUnauthorizedError(CohereError): + """Exception for unauthorized access to Cohere APIs""" + + def __init__( + self, message: Optional[str] = None, send_message_in_event: bool = False + ): + super().__init__(message=message, status_code=401, send_message_in_event=send_message_in_event) + + class ImageToTextError(NodeError): """Exception for issues that occur in the ImageToText node""" diff --git a/haystack/nodes/retriever/_embedding_encoder.py b/haystack/nodes/retriever/_embedding_encoder.py index 0f549c39d0..47a07f6cf2 100644 --- a/haystack/nodes/retriever/_embedding_encoder.py +++ b/haystack/nodes/retriever/_embedding_encoder.py @@ -23,7 +23,7 @@ HAYSTACK_REMOTE_API_MAX_RETRIES, HAYSTACK_REMOTE_API_TIMEOUT_SEC, ) -from haystack.errors import CohereError +from haystack.errors import CohereError, CohereUnauthorizedError from haystack.modeling.data_handler.dataloader import NamedDataLoader from haystack.modeling.data_handler.dataset import convert_features_to_dataset, flatten_rename from haystack.modeling.infer import Inferencer @@ -389,6 +389,8 @@ def embed(self, model: str, text: List[str]) -> np.ndarray: response = requests.request("POST", self.url, headers=headers, data=json.dumps(payload), timeout=COHERE_TIMEOUT) res = json.loads(response.text) if response.status_code != 200: + if response.status_code == 401: + raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}") raise CohereError(response.text, status_code=response.status_code) generated_embeddings = [e for e in res["embeddings"]] return np.array(generated_embeddings) diff --git a/haystack/utils/openai_utils.py b/haystack/utils/openai_utils.py index 3203524122..a3e1516496 100644 --- a/haystack/utils/openai_utils.py +++ b/haystack/utils/openai_utils.py @@ -9,7 +9,7 @@ from transformers import GPT2TokenizerFast -from haystack.errors import OpenAIError, OpenAIRateLimitError +from haystack.errors import OpenAIError, OpenAIRateLimitError, OpenAIUnauthorizedError from haystack.utils.reflection import retry_with_exponential_backoff from haystack.environment import ( HAYSTACK_REMOTE_API_BACKOFF_SEC, @@ -102,6 +102,8 @@ def openai_request(url: str, headers: Dict, payload: Dict, timeout: Union[float, openai_error: OpenAIError if response.status_code == 429: openai_error = OpenAIRateLimitError(f"API rate limit exceeded: {response.text}") + if response.status_code == 401: + openai_error = OpenAIUnauthorizedError(f"API key is invalid: {response.text}") else: openai_error = OpenAIError( f"OpenAI returned an error.\n" From ce455fc12169e9a7789b7c29e3ef239b90d85bd3 Mon Sep 17 00:00:00 2001 From: Vladimir Blagojevic Date: Tue, 14 Mar 2023 13:37:41 +0100 Subject: [PATCH 2/6] Fix black, pylint, mypy --- haystack/errors.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/haystack/errors.py b/haystack/errors.py index c6150e2b81..20f7e4c4db 100644 --- a/haystack/errors.py +++ b/haystack/errors.py @@ -171,9 +171,7 @@ def __init__( class CohereUnauthorizedError(CohereError): """Exception for unauthorized access to Cohere APIs""" - def __init__( - self, message: Optional[str] = None, send_message_in_event: bool = False - ): + def __init__(self, message: Optional[str] = None, send_message_in_event: bool = False): super().__init__(message=message, status_code=401, send_message_in_event=send_message_in_event) From 40bd2ab3430876cb7f3af240b1affb169829faf5 Mon Sep 17 00:00:00 2001 From: Florian Hardow <10029805+FHardow@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:28:02 +0100 Subject: [PATCH 3/6] Update haystack/nodes/retriever/_embedding_encoder.py Co-authored-by: Silvano Cerza <3314350+silvanocerza@users.noreply.github.com> --- haystack/nodes/retriever/_embedding_encoder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haystack/nodes/retriever/_embedding_encoder.py b/haystack/nodes/retriever/_embedding_encoder.py index 47a07f6cf2..7cfa5a4a31 100644 --- a/haystack/nodes/retriever/_embedding_encoder.py +++ b/haystack/nodes/retriever/_embedding_encoder.py @@ -388,10 +388,10 @@ def embed(self, model: str, text: List[str]) -> np.ndarray: headers = {"Authorization": f"BEARER {self.api_key}", "Content-Type": "application/json"} response = requests.request("POST", self.url, headers=headers, data=json.dumps(payload), timeout=COHERE_TIMEOUT) res = json.loads(response.text) - if response.status_code != 200: if response.status_code == 401: raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}") - raise CohereError(response.text, status_code=response.status_code) + elif response.status_code != 200: + raise CohereError(response.text, status_code=response.status_code) generated_embeddings = [e for e in res["embeddings"]] return np.array(generated_embeddings) From 1bcb1d3b576256fdba5b002c4e27fc1112dd3d4e Mon Sep 17 00:00:00 2001 From: Florian Hardow <10029805+FHardow@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:28:09 +0100 Subject: [PATCH 4/6] Update haystack/utils/openai_utils.py Co-authored-by: Silvano Cerza <3314350+silvanocerza@users.noreply.github.com> --- haystack/utils/openai_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/utils/openai_utils.py b/haystack/utils/openai_utils.py index a3e1516496..a44f1e813e 100644 --- a/haystack/utils/openai_utils.py +++ b/haystack/utils/openai_utils.py @@ -102,7 +102,7 @@ def openai_request(url: str, headers: Dict, payload: Dict, timeout: Union[float, openai_error: OpenAIError if response.status_code == 429: openai_error = OpenAIRateLimitError(f"API rate limit exceeded: {response.text}") - if response.status_code == 401: + elif response.status_code == 401: openai_error = OpenAIUnauthorizedError(f"API key is invalid: {response.text}") else: openai_error = OpenAIError( From c30b47cc944d345c40fa284e08c5cfd6aa43a99d Mon Sep 17 00:00:00 2001 From: Florian Hardow Date: Tue, 14 Mar 2023 17:32:02 +0100 Subject: [PATCH 5/6] chore: blackify project --- haystack/nodes/retriever/_embedding_encoder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/haystack/nodes/retriever/_embedding_encoder.py b/haystack/nodes/retriever/_embedding_encoder.py index 7cfa5a4a31..4b804d4f00 100644 --- a/haystack/nodes/retriever/_embedding_encoder.py +++ b/haystack/nodes/retriever/_embedding_encoder.py @@ -388,10 +388,10 @@ def embed(self, model: str, text: List[str]) -> np.ndarray: headers = {"Authorization": f"BEARER {self.api_key}", "Content-Type": "application/json"} response = requests.request("POST", self.url, headers=headers, data=json.dumps(payload), timeout=COHERE_TIMEOUT) res = json.loads(response.text) - if response.status_code == 401: - raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}") - elif response.status_code != 200: - raise CohereError(response.text, status_code=response.status_code) + if response.status_code == 401: + raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}") + elif response.status_code != 200: + raise CohereError(response.text, status_code=response.status_code) generated_embeddings = [e for e in res["embeddings"]] return np.array(generated_embeddings) From c4ca3db20d060deb60ebcd7f9b66b83e0bce747a Mon Sep 17 00:00:00 2001 From: Florian Hardow Date: Tue, 14 Mar 2023 17:38:44 +0100 Subject: [PATCH 6/6] chore: fix liniting error (remove elif after raise) --- haystack/nodes/retriever/_embedding_encoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haystack/nodes/retriever/_embedding_encoder.py b/haystack/nodes/retriever/_embedding_encoder.py index 4b804d4f00..22d7c0366a 100644 --- a/haystack/nodes/retriever/_embedding_encoder.py +++ b/haystack/nodes/retriever/_embedding_encoder.py @@ -390,7 +390,7 @@ def embed(self, model: str, text: List[str]) -> np.ndarray: res = json.loads(response.text) if response.status_code == 401: raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}") - elif response.status_code != 200: + if response.status_code != 200: raise CohereError(response.text, status_code=response.status_code) generated_embeddings = [e for e in res["embeddings"]] return np.array(generated_embeddings)