diff --git a/src/apify/_proxy_configuration.py b/src/apify/_proxy_configuration.py index 6fa64f56..1d5b9f72 100644 --- a/src/apify/_proxy_configuration.py +++ b/src/apify/_proxy_configuration.py @@ -178,7 +178,9 @@ def __init__( self._country_code = country_code async def initialize(self) -> None: - """Load the Apify Proxy password if the API token is provided and check access to Apify Proxy and proxy groups. + """Check if using proxy, if so, check the access. + + Load the Apify Proxy password from API (only if not passed to constructor or through env var). Only called if Apify Proxy configuration is used. Also checks if country has access to Apify Proxy groups if the country code is provided. @@ -187,7 +189,17 @@ async def initialize(self) -> None: `ProxyConfiguration` instance instead of calling this manually. """ if self._uses_apify_proxy: - await self._maybe_fetch_password() + if not self._password: + await self._maybe_fetch_password() + if not self._password: + raise ValueError( + 'Apify Proxy password must be provided using the "password" constructor argument ' + f'or the "{ApifyEnvVars.PROXY_PASSWORD}" environment variable. ' + f'You can also provide your Apify token via the "${ApifyEnvVars.TOKEN}" environment variable, ' + f'so that the SDK can fetch the proxy password from Apify API, ' + f'when not provided through constructor or ${ApifyEnvVars.PROXY_PASSWORD}.' + ) + await self._check_access() async def new_proxy_info( @@ -255,22 +267,7 @@ async def _maybe_fetch_password(self) -> None: user_info = await self._apify_client.user().get() if user_info: password = user_info['proxy']['password'] - - if self._password: - if self._password != password: - logger.warning( - 'The Apify Proxy password you provided belongs to a different user than the Apify ' - 'token you are using. Are you sure this is correct?' - ) - else: - self._password = password - - if not self._password: - raise ValueError( - 'Apify Proxy password must be provided using the "password" constructor argument ' - f'or the "{ApifyEnvVars.PROXY_PASSWORD}" environment variable. If you add ' - f'the "{ApifyEnvVars.TOKEN}" environment variable, the password will be automatically inferred.' - ) + self._password = password async def _check_access(self) -> None: proxy_status_url = f'{self._configuration.proxy_status_url}/?format=json' diff --git a/tests/unit/test_proxy_configuration.py b/tests/unit/test_proxy_configuration.py index fe10aefb..96eb0544 100644 --- a/tests/unit/test_proxy_configuration.py +++ b/tests/unit/test_proxy_configuration.py @@ -432,6 +432,36 @@ async def test_initialize_with_manual_password(monkeypatch: pytest.MonkeyPatch, assert proxy_configuration.is_man_in_the_middle is False +async def test_initialize_prefering_password_from_env_over_calling_api( + monkeypatch: pytest.MonkeyPatch, + respx_mock: MockRouter, + patched_apify_client: ApifyClientAsync, +) -> None: + dummy_proxy_status_url = 'http://dummy-proxy-status-url.com' + monkeypatch.setenv(ApifyEnvVars.PROXY_STATUS_URL.value, dummy_proxy_status_url) + monkeypatch.setenv(ApifyEnvVars.PROXY_PASSWORD.value, DUMMY_PASSWORD) + + respx_mock.get(dummy_proxy_status_url).mock( + httpx.Response( + 200, + json={ + 'connected': True, + 'connectionError': None, + 'isManInTheMiddle': False, + }, + ) + ) + + proxy_configuration = ProxyConfiguration() + + await proxy_configuration.initialize() + + assert proxy_configuration._password == DUMMY_PASSWORD + assert proxy_configuration.is_man_in_the_middle is False + + assert len(patched_apify_client.calls['user']['get']) == 0 # type: ignore[attr-defined] + + @pytest.mark.skip(reason='There are issues with log propagation to caplog, see issue #462.') async def test_initialize_with_manual_password_different_than_user_one( monkeypatch: pytest.MonkeyPatch,