Python: Improved exception messages in client initialization (#539)

* Improved exception messages in client initialization

* Fixed tests
This commit is contained in:
Dmytro Struk
2025-08-28 13:52:59 -07:00
committed by GitHub
Unverified
parent f5043e4fc1
commit 0c28935382
8 changed files with 47 additions and 23 deletions
@@ -86,7 +86,10 @@ class AzureAssistantsClient(OpenAIAssistantsClient):
raise ServiceInitializationError("Failed to create Azure OpenAI settings.", ex) from ex
if not azure_openai_settings.chat_deployment_name:
raise ServiceInitializationError("The Azure OpenAI deployment name is required.")
raise ServiceInitializationError(
"Azure OpenAI deployment name is required. Set via 'deployment_name' parameter "
"or 'AZURE_OPENAI_CHAT_DEPLOYMENT_NAME' environment variable."
)
# Handle authentication: try API key first, then AD token, then Entra ID
if (
@@ -98,15 +98,16 @@ class AzureChatClient(AzureOpenAIConfigBase, OpenAIChatClientBase):
raise ServiceInitializationError(f"Failed to validate settings: {exc}") from exc
if not azure_openai_settings.chat_deployment_name:
raise ServiceInitializationError("chat_deployment_name is required.")
if not azure_openai_settings.api_version:
raise ServiceInitializationError("api_version is required.")
raise ServiceInitializationError(
"Azure OpenAI deployment name is required. Set via 'deployment_name' parameter "
"or 'AZURE_OPENAI_CHAT_DEPLOYMENT_NAME' environment variable."
)
super().__init__(
deployment_name=azure_openai_settings.chat_deployment_name,
endpoint=azure_openai_settings.endpoint,
base_url=azure_openai_settings.base_url,
api_version=azure_openai_settings.api_version,
api_version=azure_openai_settings.api_version, # type: ignore
api_key=azure_openai_settings.api_key.get_secret_value() if azure_openai_settings.api_key else None,
ad_token=ad_token,
ad_token_provider=ad_token_provider,
@@ -94,15 +94,16 @@ class AzureResponsesClient(AzureOpenAIConfigBase, OpenAIResponsesClientBase):
raise ServiceInitializationError(f"Failed to validate settings: {exc}") from exc
if not azure_openai_settings.responses_deployment_name:
raise ServiceInitializationError("responses_deployment_name is required.")
if not azure_openai_settings.api_version:
raise ServiceInitializationError("api_version is required.")
raise ServiceInitializationError(
"Azure OpenAI deployment name is required. Set via 'deployment_name' parameter "
"or 'AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME' environment variable."
)
super().__init__(
deployment_name=azure_openai_settings.responses_deployment_name,
endpoint=azure_openai_settings.endpoint,
base_url=azure_openai_settings.base_url,
api_version=azure_openai_settings.api_version,
api_version=azure_openai_settings.api_version, # type: ignore
api_key=azure_openai_settings.api_key.get_secret_value() if azure_openai_settings.api_key else None,
ad_token=ad_token,
ad_token_provider=ad_token_provider,
@@ -157,14 +157,20 @@ class FoundryChatClient(ChatClientBase):
should_close_client = False
if client is None:
if not foundry_settings.project_endpoint:
raise ServiceInitializationError("Project endpoint is required when client is not provided.")
raise ServiceInitializationError(
"Foundry project endpoint is required. Set via 'project_endpoint' parameter "
"or 'FOUNDRY_PROJECT_ENDPOINT' environment variable."
)
if agent_id is None and not foundry_settings.model_deployment_name:
raise ServiceInitializationError("Model deployment name is required for agent creation.")
raise ServiceInitializationError(
"Foundry model deployment name is required. Set via 'model_deployment_name' parameter "
"or 'FOUNDRY_MODEL_DEPLOYMENT_NAME' environment variable."
)
# Use provided credential
if not async_credential:
raise ServiceInitializationError("Azure AD credential is required when client is not provided.")
raise ServiceInitializationError("Azure credential is required when client is not provided.")
client = AIProjectClient(endpoint=foundry_settings.project_endpoint, credential=async_credential)
should_close_client = True
@@ -131,9 +131,7 @@ def test_foundry_chat_client_init_missing_project_endpoint() -> None:
mock_settings_instance.agent_name = "test-agent"
mock_settings.return_value = mock_settings_instance
with pytest.raises(
ServiceInitializationError, match="Project endpoint is required when client is not provided"
):
with pytest.raises(ServiceInitializationError, match="project endpoint is required"):
FoundryChatClient(
client=None,
agent_id=None,
@@ -153,7 +151,7 @@ def test_foundry_chat_client_init_missing_model_deployment_for_agent_creation()
mock_settings_instance.agent_name = "test-agent"
mock_settings.return_value = mock_settings_instance
with pytest.raises(ServiceInitializationError, match="Model deployment name is required for agent creation"):
with pytest.raises(ServiceInitializationError, match="model deployment name is required"):
FoundryChatClient(
client=None,
agent_id=None, # No existing agent
@@ -194,7 +192,7 @@ def test_foundry_chat_client_from_dict(mock_ai_project_client: MagicMock) -> Non
def test_foundry_chat_client_init_missing_credential(foundry_unit_test_env: dict[str, str]) -> None:
"""Test FoundryChatClient.__init__ when async_credential is missing and no client provided."""
with pytest.raises(ServiceInitializationError, match="Azure AD credential is required when client is not provided"):
with pytest.raises(ServiceInitializationError, match="Azure credential is required when client is not provided"):
FoundryChatClient(
client=None,
agent_id="existing-agent",
@@ -107,9 +107,14 @@ class OpenAIAssistantsClient(OpenAIConfigBase, ChatClientBase):
raise ServiceInitializationError("Failed to create OpenAI settings.", ex) from ex
if not async_client and not openai_settings.api_key:
raise ServiceInitializationError("The OpenAI API key is required.")
raise ServiceInitializationError(
"OpenAI API key is required. Set via 'api_key' parameter or 'OPENAI_API_KEY' environment variable."
)
if not openai_settings.chat_model_id:
raise ServiceInitializationError("The OpenAI model ID is required.")
raise ServiceInitializationError(
"OpenAI model ID is required. "
"Set via 'ai_model_id' parameter or 'OPENAI_CHAT_MODEL_ID' environment variable."
)
super().__init__(
ai_model_id=openai_settings.chat_model_id,
@@ -417,9 +417,14 @@ class OpenAIChatClient(OpenAIConfigBase, OpenAIChatClientBase):
raise ServiceInitializationError("Failed to create OpenAI settings.", ex) from ex
if not async_client and not openai_settings.api_key:
raise ServiceInitializationError("The OpenAI API key is required.")
raise ServiceInitializationError(
"OpenAI API key is required. Set via 'api_key' parameter or 'OPENAI_API_KEY' environment variable."
)
if not openai_settings.chat_model_id:
raise ServiceInitializationError("The OpenAI model ID is required.")
raise ServiceInitializationError(
"OpenAI model ID is required. "
"Set via 'ai_model_id' parameter or 'OPENAI_CHAT_MODEL_ID' environment variable."
)
super().__init__(
ai_model_id=openai_settings.chat_model_id,
@@ -862,9 +862,14 @@ class OpenAIResponsesClient(OpenAIConfigBase, OpenAIResponsesClientBase):
raise ServiceInitializationError("Failed to create OpenAI settings.", ex) from ex
if not async_client and not openai_settings.api_key:
raise ServiceInitializationError("The OpenAI API key is required.")
raise ServiceInitializationError(
"OpenAI API key is required. Set via 'api_key' parameter or 'OPENAI_API_KEY' environment variable."
)
if not openai_settings.responses_model_id:
raise ServiceInitializationError("The OpenAI model ID is required.")
raise ServiceInitializationError(
"OpenAI model ID is required. "
"Set via 'ai_model_id' parameter or 'OPENAI_RESPONSES_MODEL_ID' environment variable."
)
super().__init__(
ai_model_id=openai_settings.responses_model_id,