diff --git a/CHANGES.md b/CHANGES.md index cbd6342..7926b29 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Release History +## 1.32.1 (2023-11-14) + +- FIX: Add the support of `no_sign_request` in `s3` functions + ## 1.32.0 (2023-11-13) - **BREAKING CHANGE**: Change the order of `files.save_json` function to fit `files.save_obj`. Older order is deprecated. diff --git a/CI/SCRIPTS/test_s3.py b/CI/SCRIPTS/test_s3.py index 9616a07..af1443f 100644 --- a/CI/SCRIPTS/test_s3.py +++ b/CI/SCRIPTS/test_s3.py @@ -16,6 +16,7 @@ # limitations under the License. """ Script testing the CI """ import pytest +import rasterio from cloudpathlib import AnyPath, S3Client from tempenv import tempenv @@ -62,3 +63,16 @@ def test_s3(): without_s3() with_s3() + + +def test_no_sign_request(): + with tempenv.TemporaryEnvironment( + {"AWS_S3_ENDPOINT": "s3.us-west-2.amazonaws.com"} + ): + with temp_s3(no_sign_request=True): + path = AnyPath( + "s3://sentinel-cogs/sentinel-s2-l2a-cogs/40/V/DR/2023/11/S2A_40VDR_20231114_0_L2A" + ) + assert path.exists() + with rasterio.open(str(path / "B12.tif")) as ds: + assert ds.meta["dtype"] == "uint16" diff --git a/sertit/s3.py b/sertit/s3.py index e0881dd..36957bd 100644 --- a/sertit/s3.py +++ b/sertit/s3.py @@ -63,6 +63,7 @@ def s3_env(*args, **kwargs): use_s3 = kwargs.get("use_s3_env_var", USE_S3_STORAGE) default_endpoint = kwargs.get("default_endpoint") requester_pays = kwargs.get("requester_pays") + no_sign_request = kwargs.get("no_sign_request") def decorator(function): @wraps(function) @@ -80,6 +81,7 @@ def s3_env_wrapper(*_args, **_kwargs): AWS_VIRTUAL_HOSTING=False, AWS_S3_ENDPOINT=os.getenv(AWS_S3_ENDPOINT, default_endpoint), GDAL_DISABLE_READDIR_ON_OPEN=False, + AWS_NO_SIGN_REQUEST="YES" if no_sign_request else "NO", AWS_REQUEST_PAYER="requester" if requester_pays else None, ): function(*_args, **_kwargs) @@ -96,13 +98,18 @@ def s3_env_wrapper(*_args, **_kwargs): @contextmanager def temp_s3( - default_endpoint: str = None, requester_pays: bool = False, **kwargs + default_endpoint: str = None, + requester_pays: bool = False, + no_sign_request: bool = False, + **kwargs, ) -> None: """ Initialize a temporary S3 environment as a context manager Args: - default_endpoint (str):Default Endpoint to look for + default_endpoint (str): Default Endpoint to look for + requester_pays (bool): True if the endpoint says 'requester pays' + no_sign_request (bool): True if the endpoint is open access """ import rasterio @@ -113,19 +120,33 @@ def temp_s3( AWS_VIRTUAL_HOSTING=False, AWS_S3_ENDPOINT=os.getenv(AWS_S3_ENDPOINT, default_endpoint), GDAL_DISABLE_READDIR_ON_OPEN=False, + AWS_NO_SIGN_REQUEST="YES" if no_sign_request else "NO", AWS_REQUEST_PAYER="requester" if requester_pays else None, ): yield define_s3_client( - default_endpoint, requester_pays=requester_pays, **kwargs + default_endpoint, + requester_pays=requester_pays, + no_sign_request=no_sign_request, + **kwargs, ) finally: # Clean env S3Client().set_as_default_client() -def define_s3_client(default_endpoint=None, requester_pays: bool = False, **kwargs): +def define_s3_client( + default_endpoint=None, + requester_pays: bool = False, + no_sign_request: bool = False, + **kwargs, +): """ Define S3 client + + Args: + default_endpoint (str): Default Endpoint to look for + requester_pays (bool): True if the endpoint says 'requester pays' + no_sign_request (bool): True if the endpoint is open access """ extra_args = kwargs.pop("extra_args", {}) if requester_pays: @@ -136,6 +157,7 @@ def define_s3_client(default_endpoint=None, requester_pays: bool = False, **kwar endpoint_url=f"https://{os.getenv(AWS_S3_ENDPOINT, default_endpoint)}", aws_access_key_id=os.getenv(AWS_ACCESS_KEY_ID), aws_secret_access_key=os.getenv(AWS_SECRET_ACCESS_KEY), + no_sign_request=no_sign_request, extra_args=extra_args, **kwargs, )