diff --git a/litellm/llms/github_copilot/authenticator.py b/litellm/llms/github_copilot/authenticator.py index 495ede79bfd..71e43f923bf 100644 --- a/litellm/llms/github_copilot/authenticator.py +++ b/litellm/llms/github_copilot/authenticator.py @@ -16,7 +16,6 @@ from .common_utils import ( get_copilot_auth_headers, ) - # Constants (default values — overridable via environment variables at call time) DEFAULT_GITHUB_CLIENT_ID: Final = "Iv1.b507a08c87ecfe98" DEFAULT_GITHUB_DEVICE_CODE_URL: Final = "https://github.com/login/device/code" @@ -97,7 +96,7 @@ class Authenticator: return self.get_access_token() except GetAccessTokenError as e: raise GetAPIKeyError( - message=f"Failed to get OAuth access token: {str(e)}", + message=f"Failed to get OAuth access token: {e!s}", status_code=401, ) diff --git a/litellm/llms/github_copilot/common_utils.py b/litellm/llms/github_copilot/common_utils.py index ad5d05184b2..0712487afb3 100644 --- a/litellm/llms/github_copilot/common_utils.py +++ b/litellm/llms/github_copilot/common_utils.py @@ -4,7 +4,6 @@ Constants for Copilot integration import os from typing import Final -from uuid import uuid4 import httpx diff --git a/tests/test_litellm/llms/github_copilot/responses/test_github_copilot_responses_transformation.py b/tests/test_litellm/llms/github_copilot/responses/test_github_copilot_responses_transformation.py index ff948c14cb7..9fe0a1aee49 100644 --- a/tests/test_litellm/llms/github_copilot/responses/test_github_copilot_responses_transformation.py +++ b/tests/test_litellm/llms/github_copilot/responses/test_github_copilot_responses_transformation.py @@ -7,8 +7,8 @@ transformations for the Responses API. Source: litellm/llms/github_copilot/responses/transformation.py """ -from unittest.mock import patch, MagicMock - +import os +from unittest.mock import MagicMock, patch import pytest import litellm @@ -100,7 +100,9 @@ class TestGithubCopilotResponsesAPITransformation: assert "x-request-id" not in headers assert "x-vscode-user-agent-library-version" not in headers - @patch("litellm.llms.github_copilot.responses.transformation.Authenticator") + @patch( # test-quality-ok: matches the Authenticator-mocking convention already used throughout this file + "litellm.llms.github_copilot.responses.transformation.Authenticator" + ) def test_validate_environment_headers_from_environment(self, mock_authenticator_class): mock_auth_instance = MagicMock() mock_auth_instance.get_api_key.return_value = "test-api-key-123" @@ -133,7 +135,9 @@ class TestGithubCopilotResponsesAPITransformation: assert headers["x-github-api-version"] == "2099-01-01" assert headers["x-vscode-user-agent-library-version"] == "custom-library" - @patch("litellm.llms.github_copilot.responses.transformation.Authenticator") + @patch( # test-quality-ok: matches the Authenticator-mocking convention already used throughout this file + "litellm.llms.github_copilot.responses.transformation.Authenticator" + ) def test_empty_environment_header_omits_default(self, mock_authenticator_class): mock_auth_instance = MagicMock() mock_auth_instance.get_api_key.return_value = "test-api-key-123" diff --git a/tests/test_litellm/llms/github_copilot/test_github_copilot_authenticator.py b/tests/test_litellm/llms/github_copilot/test_github_copilot_authenticator.py index beca19f82e4..95b66efa16e 100644 --- a/tests/test_litellm/llms/github_copilot/test_github_copilot_authenticator.py +++ b/tests/test_litellm/llms/github_copilot/test_github_copilot_authenticator.py @@ -1,3 +1,4 @@ +import logging import os from unittest.mock import MagicMock, mock_open, patch @@ -69,15 +70,16 @@ class TestGitHubCopilotAuthenticator: "https://api.githubcopilot.com#fragment", ), ) - def test_get_api_base_rejects_insecure_configuration(self, authenticator, api_base): + def test_get_api_base_rejects_insecure_configuration(self, authenticator, api_base, caplog): with ( patch.dict(os.environ, {"GITHUB_COPILOT_API_BASE": api_base}, clear=True), - patch("litellm.llms.github_copilot.authenticator.verbose_logger.warning") as mock_warning, + caplog.at_level(logging.WARNING, logger="LiteLLM"), ): assert authenticator.get_api_base() is None - mock_warning.assert_called_once_with( + assert ( "Ignoring GITHUB_COPILOT_API_BASE because it must be an HTTPS URL without credentials, query, or fragment" + in caplog.text ) def test_get_api_base_uses_default_when_unconfigured(self, authenticator): @@ -92,19 +94,20 @@ class TestGitHubCopilotAuthenticator: ): assert authenticator.get_api_base("https://deployment.example.com") == "https://deployment.example.com" - def test_get_api_base_falls_back_from_untrusted_deployment_endpoint(self, authenticator): + def test_get_api_base_falls_back_from_untrusted_deployment_endpoint(self, authenticator, caplog): with ( patch.dict( os.environ, {"GITHUB_COPILOT_API_BASE": "https://configured.example.com"}, clear=True, ), - patch("litellm.llms.github_copilot.authenticator.verbose_logger.warning") as mock_warning, + caplog.at_level(logging.WARNING, logger="LiteLLM"), ): assert authenticator.get_api_base("http://attacker.example.com") == "https://configured.example.com" - mock_warning.assert_called_once_with( + assert ( "Ignoring deployment api_base because it must be an HTTPS URL without credentials, query, or fragment" + in caplog.text ) def test_get_github_headers(self, authenticator): @@ -203,19 +206,19 @@ class TestGitHubCopilotAuthenticator: mock_login.assert_called_once() write_open().write.assert_called_once_with(mock_token) - def test_get_access_token_survives_persistence_failure(self, authenticator): + def test_get_access_token_survives_persistence_failure(self, authenticator, caplog): mock_token = "mock-access-token" with ( patch.object(authenticator, "_login", return_value=mock_token) as mock_login, patch("builtins.open", side_effect=IOError), - patch("litellm.llms.github_copilot.authenticator.verbose_logger.error") as mock_error, + caplog.at_level(logging.ERROR, logger="LiteLLM"), ): token = authenticator.get_access_token() assert token == mock_token mock_login.assert_called_once() - mock_error.assert_called_once_with("Error saving access token to file") + assert "Error saving access token to file" in caplog.text def test_get_access_token_failure(self, authenticator): """Test that an exception is raised after multiple login failures."""