From ccb83c31c23da753b93e2595d4a92f0caf026f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Luk=C5=A1i=C4=8D?= <31988337+zigaLuksic@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:02:22 +0100 Subject: [PATCH 1/2] Update session caching according to core auth changes (#509) * adjust session caching and other tests * prepare for release * simplify token info test --- CHANGELOG.MD | 4 ++++ sentinelhub/_version.py | 2 +- sentinelhub/download/sentinelhub_client.py | 2 +- tests/api/test_process.py | 4 ++-- tests/download/test_session.py | 9 +++------ 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c1d1447a..664a89d6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,7 @@ +## [Version 3.10.0] - 2023-12-07 + +- Adjust session caching to mirror changes to the core services. Older version might no longer correctly cache sessions. + ## [Version 3.9.5] - 2023-12-07 - The `SentinelHubDownloadClient` class now has a `default_retry_time` parameter, which allows control over the waiting time when a request gets a 429 TOO_MANY_REQUESTS response without a specific retry time in the headers. The default value for this behavior has been changed from 0s to 30s to avoid edge-cases where SH services were bombarded with requests. diff --git a/sentinelhub/_version.py b/sentinelhub/_version.py index b2c3350a..c349e6ed 100644 --- a/sentinelhub/_version.py +++ b/sentinelhub/_version.py @@ -1,3 +1,3 @@ """Version of the sentinelhub package.""" -__version__ = "3.9.5" +__version__ = "3.10.0" diff --git a/sentinelhub/download/sentinelhub_client.py b/sentinelhub/download/sentinelhub_client.py index 93fa267b..af79fef4 100644 --- a/sentinelhub/download/sentinelhub_client.py +++ b/sentinelhub/download/sentinelhub_client.py @@ -194,7 +194,7 @@ def _get_cache_key(config_or_session: SentinelHubSession | SHConfig) -> tuple[st base_url = config_or_session.config.sh_base_url # If session was generated from token then config_or_session.config.sh_client_id could have wrong client id. - sh_client_id = config_or_session.info().get("aud", "") + sh_client_id = config_or_session.info().get("azp", "") if not sh_client_id: warnings.warn( "Failed to read client ID from OAuth token. Session caching might not work correctly.", diff --git a/tests/api/test_process.py b/tests/api/test_process.py index 7a52bb69..f9e09c75 100644 --- a/tests/api/test_process.py +++ b/tests/api/test_process.py @@ -7,7 +7,7 @@ from typing import Any import pytest -from oauthlib.oauth2.rfc6749.errors import CustomOAuth2Error +from oauthlib.oauth2.rfc6749.errors import InvalidClientError from shapely.geometry import Polygon from sentinelhub import ( @@ -483,7 +483,7 @@ def test_bad_credentials() -> None: bad_credentials_config.sh_client_id = "test" request = SentinelHubRequest(**request_params, config=bad_credentials_config) - with pytest.raises(CustomOAuth2Error): + with pytest.raises(InvalidClientError): request.get_data() missing_credentials_config = SHConfig() diff --git a/tests/download/test_session.py b/tests/download/test_session.py index 6e3e9321..9cc975ae 100644 --- a/tests/download/test_session.py +++ b/tests/download/test_session.py @@ -5,7 +5,7 @@ from typing import Any import pytest -from oauthlib.oauth2.rfc6749.errors import CustomOAuth2Error +from oauthlib.oauth2.rfc6749.errors import CustomOAuth2Error, InvalidClientError from requests_mock import Mocker from sentinelhub import SentinelHubSession, SHConfig, __version__ @@ -48,10 +48,7 @@ def test_session(session: SentinelHubSession) -> None: @pytest.mark.sh_integration() def test_token_info(session: SentinelHubSession) -> None: - info = session.info() - - for key in ["sub", "aud", "jti", "exp", "name", "email", "sid", "org", "did", "aid", "d"]: - assert key in info + assert "azp" in session.info() def test_session_content_and_headers(fake_config: SHConfig, fake_token: dict[str, Any], requests_mock: Mocker) -> None: @@ -108,7 +105,7 @@ def test_refreshing_procedure(fake_token: JsonDict, fake_config: SHConfig) -> No assert session.token == fake_token session = SentinelHubSession(config=fake_config, refresh_before_expiry=500, _token=fake_token) - with pytest.raises(CustomOAuth2Error): + with pytest.raises(InvalidClientError): _ = session.token From 6616e79541e8098f38ee7041f8e6c09ba52e9d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Luk=C5=A1i=C4=8D?= <31988337+zigaLuksic@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:04:22 +0100 Subject: [PATCH 2/2] Change auth endpoint default (#510) * change default oauth endpoint * fix tests --- sentinelhub/config.py | 2 +- tests/download/test_session.py | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/sentinelhub/config.py b/sentinelhub/config.py index 8b31f3ea..a61b6023 100644 --- a/sentinelhub/config.py +++ b/sentinelhub/config.py @@ -30,7 +30,7 @@ class _SHConfig: sh_client_secret: str = "" sh_base_url: str = "https://services.sentinel-hub.com" sh_auth_base_url: str | None = None - sh_token_url: str = "https://services.sentinel-hub.com/oauth/token" + sh_token_url: str = "https://services.sentinel-hub.com/auth/realms/main/protocol/openid-connect/token" geopedia_wms_url: str = "https://service.geopedia.world" geopedia_rest_url: str = "https://www.geopedia.world/rest" aws_access_key_id: str = "" diff --git a/tests/download/test_session.py b/tests/download/test_session.py index 9cc975ae..643eb889 100644 --- a/tests/download/test_session.py +++ b/tests/download/test_session.py @@ -53,7 +53,7 @@ def test_token_info(session: SentinelHubSession) -> None: def test_session_content_and_headers(fake_config: SHConfig, fake_token: dict[str, Any], requests_mock: Mocker) -> None: """Make sure correct content and headers are passed to the service.""" - requests_mock.post(url="/oauth/token", response_list=[{"json": fake_token}]) + requests_mock.post(url=fake_config.sh_token_url, response_list=[{"json": fake_token}]) call_time = time.time() token = SentinelHubSession(config=fake_config).token # "expires_at" is derived from "expires_in" and not read from the response field "expires_at" @@ -125,11 +125,7 @@ def test_oauth_compliance_hook_4xx( expected_exception: type[Exception], fake_config: SHConfig, ) -> None: - requests_mock.post( - "https://services.sentinel-hub.com/oauth/token", - json=response_payload, - status_code=status_code, - ) + requests_mock.post(fake_config.sh_token_url, json=response_payload, status_code=status_code) with pytest.raises(expected_exception): SentinelHubSession(config=fake_config) @@ -148,11 +144,7 @@ def test_oauth_compliance_hook_4xx( def test_oauth_compliance_hook_5xx( requests_mock: Mocker, status_code: int, response_payload: JsonDict | None, fake_config: SHConfig ) -> None: - requests_mock.post( - "https://services.sentinel-hub.com/oauth/token", - json=response_payload, - status_code=status_code, - ) + requests_mock.post(fake_config.sh_token_url, json=response_payload, status_code=status_code) fake_config.max_download_attempts = 10 fake_config.download_sleep_time = 0