Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-proton-vpn-api-core for
openSUSE:Factory checked in at 2025-04-17 16:10:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-proton-vpn-api-core (Old)
and /work/SRC/openSUSE:Factory/.python-proton-vpn-api-core.new.30101 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-proton-vpn-api-core"
Thu Apr 17 16:10:14 2025 rev:8 rq:1270228 version:0.42.4
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-proton-vpn-api-core/python-proton-vpn-api-core.changes
2025-04-02 17:12:15.286558967 +0200
+++
/work/SRC/openSUSE:Factory/.python-proton-vpn-api-core.new.30101/python-proton-vpn-api-core.changes
2025-04-20 20:08:01.813266380 +0200
@@ -1,0 +2,7 @@
+Mon Apr 14 10:57:23 UTC 2025 - Richard Rahl <[email protected]>
+
+- update to 0.42.4:
+ * fix: [VPNLINUX-1191] swallow&re-schedule server refresh when we receive
HTTP code 429
+ * fix: [VPNLINUX-1191] swallow&re-schedule when we receive HTTP code 429
from refreshers
+
+-------------------------------------------------------------------
Old:
----
v0.42.3.tar.gz
New:
----
v0.42.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-proton-vpn-api-core.spec ++++++
--- /var/tmp/diff_new_pack.cSuHT1/_old 2025-04-20 20:08:02.557297651 +0200
+++ /var/tmp/diff_new_pack.cSuHT1/_new 2025-04-20 20:08:02.557297651 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-proton-vpn-api-core
-Version: 0.42.3
+Version: 0.42.4
Release: 0
Summary: Proton VPN API library
License: GPL-3.0-or-later
++++++ v0.42.3.tar.gz -> v0.42.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/certificate_refresher.py
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/certificate_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/certificate_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/certificate_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -27,6 +27,7 @@
from proton.vpn.session.credentials import VPNPubkeyCredentials
from proton.session.exceptions import (
ProtonAPINotReachable, ProtonAPINotAvailable,
+ ProtonAPIError
)
logger = logging.getLogger(__name__)
@@ -64,6 +65,13 @@
next_refresh_delay = certificate.remaining_time_to_next_refresh
self._number_of_failed_refresh_attempts = 0
await self._notify()
+ except ProtonAPIError as error:
+ if error.http_code != 429:
+ raise
+
+ logger.warning(f"Certificate refresh failed {error}")
+ next_refresh_delay = self._get_next_refresh_delay()
+ self._number_of_failed_refresh_attempts += 1
except (ProtonAPINotReachable, ProtonAPINotAvailable) as error:
logger.warning(f"Certificate refresh failed: {error}")
next_refresh_delay = self._get_next_refresh_delay()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/client_config_refresher.py
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/client_config_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/client_config_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/client_config_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -25,6 +25,7 @@
from proton.vpn import logging
from proton.session.exceptions import (
ProtonAPINotReachable, ProtonAPINotAvailable,
+ ProtonAPIError
)
logger = logging.getLogger(__name__)
@@ -54,6 +55,12 @@
try:
new_client_config = await self._session.fetch_client_config()
next_refresh_delay = new_client_config.seconds_until_expiration
+ except ProtonAPIError as error:
+ if error.http_code != 429:
+ raise
+
+ logger.warning(f"Client config refresh failed: {error}")
+ next_refresh_delay = ClientConfig.get_refresh_interval_in_seconds()
except (ProtonAPINotReachable, ProtonAPINotAvailable) as error:
logger.warning(f"Client config refresh failed: {error}")
next_refresh_delay = ClientConfig.get_refresh_interval_in_seconds()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/feature_flags_refresher.py
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/feature_flags_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/feature_flags_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/feature_flags_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -25,6 +25,7 @@
from proton.vpn import logging
from proton.session.exceptions import (
ProtonAPINotReachable, ProtonAPINotAvailable,
+ ProtonAPIError
)
logger = logging.getLogger(__name__)
@@ -53,6 +54,12 @@
try:
feature_flags = await self._session.fetch_feature_flags()
next_refresh_delay = feature_flags.seconds_until_expiration
+ except ProtonAPIError as error:
+ if error.http_code != 429:
+ raise
+
+ logger.warning(f"Feature flag refresh failed {error}")
+ next_refresh_delay = FeatureFlags.get_refresh_interval_in_seconds()
except (ProtonAPINotReachable, ProtonAPINotAvailable) as error:
logger.warning(f"Feature flag refresh failed: {error}")
next_refresh_delay = FeatureFlags.get_refresh_interval_in_seconds()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/server_list_refresher.py
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/server_list_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/proton/vpn/core/refresher/server_list_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/proton/vpn/core/refresher/server_list_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -21,6 +21,7 @@
from proton.session.exceptions import (
ProtonAPINotReachable, ProtonAPINotAvailable,
+ ProtonAPIError
)
from proton.vpn import logging
@@ -62,6 +63,12 @@
next_refresh_delay = server_list.seconds_until_expiration
else:
next_refresh_delay =
self._session.server_list.seconds_until_expiration
+ except ProtonAPIError as error:
+ if error.http_code != 429:
+ raise
+
+ logger.warning(f"Server list refresh failed: {error}")
+ next_refresh_delay =
ServerList.get_loads_refresh_interval_in_seconds()
except (ProtonAPINotReachable, ProtonAPINotAvailable) as error:
logger.warning(f"Server list refresh failed: {error}")
next_refresh_delay =
ServerList.get_loads_refresh_interval_in_seconds()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_certificate_refresher.py
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_certificate_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_certificate_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_certificate_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -22,6 +22,25 @@
from proton.vpn.core.refresher.certificate_refresher import
CertificateRefresher, generate_backoff_value
from proton.vpn.core.refresher.scheduler import RunAgain
+from proton.session.exceptions import ProtonAPIError
+
+
[email protected]
+async def
test_refresh_schedules_next_refresh_if_certificate_is_expired_and_api_error_exception_is_raised():
+ session_holder = Mock()
+ session = session_holder.session
+
+ refresher = CertificateRefresher(session_holder=session_holder)
+
+ session.fetch_certificate = AsyncMock(side_effect=ProtonAPIError(
+ http_code=429,
+ http_headers={},
+ json_data={"Code": 429, "Error": "Error message"}
+ ))
+ new_certificate = Mock()
+ new_certificate.remaining_time_to_next_refresh = 600
+
+ next_refresh_delay = await refresher.refresh()
@pytest.mark.asyncio
@@ -59,4 +78,4 @@
random_component=random_component
)
- assert backoff == expected_backoff
\ No newline at end of file
+ assert backoff == expected_backoff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_client_config_refresher.py
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_client_config_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_client_config_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_client_config_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -22,6 +22,7 @@
from proton.vpn.core.refresher.client_config_refresher import
ClientConfigRefresher
from proton.vpn.core.refresher.scheduler import RunAgain
+from proton.session.exceptions import ProtonAPIError
@pytest.mark.asyncio
@@ -40,3 +41,20 @@
session.fetch_client_config.assert_called_once()
assert next_refresh_delay ==
RunAgain.after_seconds(new_client_config.seconds_until_expiration)
+
+
[email protected]
+async def
test_refresh_schedules_next_refresh_if_client_config_is_expired_and_api_error_exception_is_raised():
+ session_holder = Mock()
+ session = session_holder.session
+ refresher = ClientConfigRefresher(session_holder=session_holder)
+
+ new_client_config = Mock()
+ new_client_config.seconds_until_expiration = 60
+ session.fetch_client_config = AsyncMock(side_effect=ProtonAPIError(
+ http_code=429,
+ http_headers={},
+ json_data={"Code": 429, "Error": "Error message"}
+ ))
+
+ next_refresh_delay = await refresher.refresh()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_feature_flags_refresher.py
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_feature_flags_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_feature_flags_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_feature_flags_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -22,6 +22,7 @@
from proton.vpn.core.refresher.feature_flags_refresher import
FeatureFlagsRefresher
from proton.vpn.core.refresher.scheduler import RunAgain
+from proton.session.exceptions import ProtonAPIError
@pytest.mark.asyncio
@@ -41,3 +42,21 @@
session.fetch_feature_flags.assert_called_once()
assert next_refresh_delay ==
RunAgain.after_seconds(new_feature_flags.seconds_until_expiration)
+
+
[email protected]
+async def
test_refresh_schedules_next_refresh_if_feature_flags_is_expired_and_api_error_exception_is_raised():
+ session_holder = Mock()
+ session = session_holder.session
+
+ refresher = FeatureFlagsRefresher(session_holder=session_holder)
+
+ new_feature_flags = Mock()
+ new_feature_flags.seconds_until_expiration = 60
+ session.fetch_feature_flags = AsyncMock(side_effect=ProtonAPIError(
+ http_code=429,
+ http_headers={},
+ json_data={"Code": 429, "Error": "Error message"}
+ ))
+
+ next_refresh_delay = await refresher.refresh()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_server_list_refresher.py
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_server_list_refresher.py
---
old/python-proton-vpn-api-core-0.42.3/tests/core/refresher/test_server_list_refresher.py
2025-02-24 15:38:38.000000000 +0100
+++
new/python-proton-vpn-api-core-0.42.4/tests/core/refresher/test_server_list_refresher.py
2025-04-07 13:04:16.000000000 +0200
@@ -16,13 +16,16 @@
You should have received a copy of the GNU General Public License
along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
"""
-from unittest.mock import Mock, AsyncMock
+from unittest.mock import Mock, AsyncMock, patch
import pytest
from proton.vpn.core.refresher.scheduler import RunAgain
from proton.vpn.core.refresher.server_list_refresher import ServerListRefresher
+from proton.session.exceptions import ProtonAPIError
+
+
@pytest.mark.asyncio
async def
test_refresh_fetches_server_list_if_expired_and_returns_next_refresh_delay():
@@ -107,3 +110,28 @@
# And the next refresh should've been scheduled when the current
# server list expires.
assert next_refresh_delay ==
RunAgain.after_seconds(session.server_list.seconds_until_expiration)
+
+
[email protected]
+@patch("proton.vpn.core.refresher.server_list_refresher.ServerList.get_loads_refresh_interval_in_seconds")
+async def
test_refresh_schedules_next_refresh_if_server_list_is_expired_and_api_error_exception_is_raised(mock_get_loads_refresh_interval_in_seconds):
+ get_loads_refresh_interval_in_seconds = 10
+ mock_get_loads_refresh_interval_in_seconds.return_value =
get_loads_refresh_interval_in_seconds
+ session_holder = Mock()
+ session = session_holder.session
+
+ # The current server list is expired.
+ session.server_list.expired = True
+
+ # Mock a 429 response from the server
+ session.fetch_server_list = AsyncMock(side_effect=ProtonAPIError(
+ http_code=429,
+ http_headers={},
+ json_data={"Code": 429, "Error": "Error message"}
+ ))
+
+ refresher = ServerListRefresher(session_holder=session_holder)
+ refresher.server_list_updated_callback = Mock()
+
+ # No error message should be raised since it's been swallowed
+ next_refresh_delay = await refresher.refresh()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-proton-vpn-api-core-0.42.3/versions.yml
new/python-proton-vpn-api-core-0.42.4/versions.yml
--- old/python-proton-vpn-api-core-0.42.3/versions.yml 2025-02-24
15:38:38.000000000 +0100
+++ new/python-proton-vpn-api-core-0.42.4/versions.yml 2025-04-07
13:04:16.000000000 +0200
@@ -1,3 +1,12 @@
+version: 0.42.4
+time: 2025/04/04 13:00
+author: Alexandru Cheltuitor
+email: [email protected]
+urgency: low
+stability: unstable
+description:
+- Swallow and re-schedule server refresh when we receive HTTP code 429.
+---
version: 0.42.3
time: 2025/02/24 12:00
author: Alexandru Cheltuitor