Skip to content

Commit 66a1a90

Browse files
committed
fix: Detect and handle watsonx.ai model provider rate limit exceptions
Issue - #1599 Summary - Fix Ruff linting errors
1 parent 7ec46fd commit 66a1a90

3 files changed

Lines changed: 31 additions & 27 deletions

File tree

src/api/provider_health.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
"""Provider health check endpoint."""
22

33
import asyncio
4-
from typing import Optional
4+
55
import httpx
66
from fastapi import Depends
77
from fastapi.responses import JSONResponse
8-
from utils.logging_config import get_logger
9-
from utils import provider_health_cache
10-
from config.settings import get_openrag_config
8+
119
from api.provider_validation import validate_provider_setup
10+
from config.settings import get_openrag_config
1211
from dependencies import get_current_user
1312
from session_manager import User
13+
from utils import provider_health_cache
14+
from utils.logging_config import get_logger
1415

1516
logger = get_logger(__name__)
1617

1718

1819
async def check_provider_health(
19-
provider: Optional[str] = None,
20+
provider: str | None = None,
2021
test_completion: bool = False,
2122
user: User = Depends(get_current_user),
2223
):

src/api/provider_validation.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""Provider validation utilities for testing API keys and models during onboarding."""
22

33
import json
4+
45
import httpx
6+
57
from utils.container_utils import transform_localhost_url
68
from utils.logging_config import get_logger
79
from utils.watsonx_retry import request_with_retry
@@ -270,7 +272,7 @@ async def _test_openai_lightweight_health(api_key: str) -> None:
270272

271273
except httpx.TimeoutException:
272274
logger.error("OpenAI lightweight health check timed out")
273-
raise Exception("OpenAI API request timed out")
275+
raise Exception("OpenAI API request timed out") from None
274276
except Exception as e:
275277
logger.error(f"OpenAI lightweight health check failed: {str(e)}")
276278
raise
@@ -340,7 +342,7 @@ async def _test_openai_completion_with_tools(api_key: str, llm_model: str) -> No
340342

341343
except httpx.TimeoutException:
342344
logger.error("OpenAI completion test timed out")
343-
raise Exception("Request timed out")
345+
raise Exception("Request timed out") from None
344346
except Exception as e:
345347
logger.error(f"OpenAI completion test failed: {str(e)}")
346348
raise
@@ -382,7 +384,7 @@ async def _test_openai_embedding(api_key: str, embedding_model: str) -> None:
382384

383385
except httpx.TimeoutException:
384386
logger.error("OpenAI embedding test timed out")
385-
raise Exception("Request timed out")
387+
raise Exception("Request timed out") from None
386388
except Exception as e:
387389
logger.error(f"OpenAI embedding test failed: {str(e)}")
388390
raise
@@ -425,7 +427,7 @@ async def _test_watsonx_lightweight_health(api_key: str, endpoint: str, project_
425427

426428
except httpx.TimeoutException:
427429
logger.error("WatsonX lightweight health check timed out")
428-
raise Exception("WatsonX API request timed out")
430+
raise Exception("WatsonX API request timed out") from None
429431
except Exception as e:
430432
logger.error(f"WatsonX lightweight health check failed: {str(e)}")
431433
raise
@@ -516,7 +518,7 @@ async def _test_watsonx_completion_with_tools(
516518

517519
except httpx.TimeoutException:
518520
logger.error("IBM Watson completion test timed out")
519-
raise Exception("Request timed out")
521+
raise Exception("Request timed out") from None
520522
except Exception as e:
521523
logger.error(f"IBM Watson completion test failed: {str(e)}")
522524
# If the error message contains JSON, parse it to extract just the message
@@ -525,7 +527,7 @@ async def _test_watsonx_completion_with_tools(
525527
json_part = error_str.split("IBM Watson API error: ", 1)[1]
526528
parsed_message = _parse_json_error_message(json_part)
527529
if parsed_message != json_part:
528-
raise Exception(f"IBM Watson API error: {parsed_message}")
530+
raise Exception(f"IBM Watson API error: {parsed_message}") from e
529531
raise
530532

531533

@@ -601,7 +603,7 @@ async def _test_watsonx_embedding(
601603

602604
except httpx.TimeoutException:
603605
logger.error("IBM Watson embedding test timed out")
604-
raise Exception("Request timed out")
606+
raise Exception("Request timed out") from None
605607
except Exception as e:
606608
logger.error(f"IBM Watson embedding test failed: {str(e)}")
607609
# If the error message contains JSON, parse it to extract just the message
@@ -610,7 +612,7 @@ async def _test_watsonx_embedding(
610612
json_part = error_str.split("IBM Watson API error: ", 1)[1]
611613
parsed_message = _parse_json_error_message(json_part)
612614
if parsed_message != json_part:
613-
raise Exception(f"IBM Watson API error: {parsed_message}")
615+
raise Exception(f"IBM Watson API error: {parsed_message}") from e
614616
raise
615617

616618

@@ -640,7 +642,7 @@ async def _test_ollama_lightweight_health(endpoint: str) -> None:
640642

641643
except httpx.TimeoutException:
642644
logger.error("Ollama lightweight health check timed out")
643-
raise Exception("Ollama endpoint timed out")
645+
raise Exception("Ollama endpoint timed out") from None
644646
except Exception as e:
645647
logger.error(f"Ollama lightweight health check failed: {str(e)}")
646648
raise
@@ -692,7 +694,7 @@ async def _test_ollama_completion_with_tools(llm_model: str, endpoint: str) -> N
692694

693695
except httpx.TimeoutException:
694696
logger.error("Ollama completion test timed out")
695-
raise httpx.TimeoutException("Ollama is busy or model inference timed out")
697+
raise httpx.TimeoutException("Ollama is busy or model inference timed out") from None
696698
except Exception as e:
697699
logger.error(f"Ollama completion test failed: {str(e)}")
698700
raise
@@ -731,7 +733,7 @@ async def _test_ollama_embedding(embedding_model: str, endpoint: str) -> None:
731733

732734
except httpx.TimeoutException:
733735
logger.error("Ollama embedding test timed out")
734-
raise httpx.TimeoutException("Ollama is busy or embedding generation timed out")
736+
raise httpx.TimeoutException("Ollama is busy or embedding generation timed out") from None
735737
except Exception as e:
736738
logger.error(f"Ollama embedding test failed: {str(e)}")
737739
raise
@@ -769,7 +771,7 @@ async def _test_anthropic_lightweight_health(api_key: str) -> None:
769771

770772
except httpx.TimeoutException:
771773
logger.error("Anthropic lightweight health check timed out")
772-
raise Exception("Anthropic API request timed out")
774+
raise Exception("Anthropic API request timed out") from None
773775
except Exception as e:
774776
logger.error(f"Anthropic lightweight health check failed: {str(e)}")
775777
raise
@@ -823,7 +825,7 @@ async def _test_anthropic_completion_with_tools(api_key: str, llm_model: str) ->
823825

824826
except httpx.TimeoutException:
825827
logger.error("Anthropic completion test timed out")
826-
raise Exception("Request timed out")
828+
raise Exception("Request timed out") from None
827829
except Exception as e:
828830
logger.error(f"Anthropic completion test failed: {str(e)}")
829831
raise

src/services/models_service.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import httpx
21
import asyncio
3-
from typing import Dict, List, Optional
2+
3+
import httpx
4+
5+
from config.embedding_constants import OPENAI_DEFAULT_EMBEDDING_MODEL, OPENAI_EMBEDDING_MODEL_PREFIX
46
from config.model_constants import (
57
ANTHROPIC_DEFAULT_LANGUAGE_MODEL,
68
ANTHROPIC_VALIDATION_MODELS,
79
OLLAMA_DEFAULT_LANGUAGE_MODEL_PATTERN,
810
OPENAI_DEFAULT_LANGUAGE_MODEL,
911
OPENAI_VALIDATION_MODELS,
1012
)
11-
from config.embedding_constants import OPENAI_DEFAULT_EMBEDDING_MODEL, OPENAI_EMBEDDING_MODEL_PREFIX
1213
from utils.container_utils import transform_localhost_url
1314
from utils.logging_config import get_logger
1415
from utils.watsonx_retry import request_with_retry
@@ -32,7 +33,7 @@ class ModelsService:
3233
"""Service for fetching available models from different AI providers and managing a model registry."""
3334

3435
# Registry for caching model-to-provider mapping
35-
_model_provider_registry: Dict[str, str] = {}
36+
_model_provider_registry: dict[str, str] = {}
3637
_registry_lock = asyncio.Lock()
3738

3839
def __init__(self):
@@ -125,7 +126,7 @@ async def update_model_registry(self):
125126
async def get_litellm_model_name(
126127
self,
127128
model_name: str,
128-
provider: Optional[str] = None,
129+
provider: str | None = None,
129130
strict: bool = False,
130131
) -> str:
131132
"""Resolve ``model_name`` to a LiteLLM-routable string.
@@ -170,7 +171,7 @@ async def get_litellm_model_name(
170171

171172
async def get_openai_models(
172173
self, api_key: str, update_index: bool = True
173-
) -> Dict[str, List[Dict[str, str]]]:
174+
) -> dict[str, list[dict[str, str]]]:
174175
"""Fetch available models from OpenAI API with lightweight validation"""
175176
try:
176177
headers = {
@@ -256,7 +257,7 @@ async def get_openai_models(
256257

257258
async def get_anthropic_models(
258259
self, api_key: str, update_index: bool = True
259-
) -> Dict[str, List[Dict[str, str]]]:
260+
) -> dict[str, list[dict[str, str]]]:
260261
"""Fetch available models from Anthropic API"""
261262
try:
262263
headers = {
@@ -324,7 +325,7 @@ async def get_anthropic_models(
324325

325326
async def get_ollama_models(
326327
self, endpoint: str = None, update_index: bool = True
327-
) -> Dict[str, List[Dict[str, str]]]:
328+
) -> dict[str, list[dict[str, str]]]:
328329
"""Fetch available models from Ollama API with tool calling capabilities for language models"""
329330
try:
330331
ollama_url = transform_localhost_url(endpoint)
@@ -446,7 +447,7 @@ async def get_ibm_models(
446447
api_key: str = None,
447448
project_id: str = None,
448449
update_index: bool = True,
449-
) -> Dict[str, List[Dict[str, str]]]:
450+
) -> dict[str, list[dict[str, str]]]:
450451
"""Fetch available models from IBM Watson API"""
451452
try:
452453
# Use provided endpoint or default

0 commit comments

Comments
 (0)